Commit 59526b7e8ee7a5050c83666509c4b52a691f7f8a
1 parent
f4a3b511
card-app 测试项目添加
Showing
20 changed files
with
1088 additions
and
1 deletions
commons/ConfigDB.py
0 → 100644
1 | +#!/usr/bin/python | |
2 | +# -*- coding: UTF-8 -*- | |
3 | +import pymysql | |
4 | +import time | |
5 | +import src.commons.common as ca | |
6 | +import json | |
7 | +from commons.Logging import Logger | |
8 | +# import chardet | |
9 | +log=Logger() | |
10 | + | |
11 | + | |
12 | +dbhost=ca.get_global_config('global_data','Database','dbhost') | |
13 | +dbport=int(ca.get_global_config('global_data','Database','dbport')) | |
14 | +dbname=ca.get_global_config('global_data','Database','dbname') | |
15 | +dbuser=ca.get_global_config('global_data','Database','dbuser') | |
16 | +dbpassword=ca.get_global_config('global_data','Database','dbpassword') | |
17 | +#dbcharset=get_global_config('Database','dbcharset') | |
18 | + | |
19 | +def mysql_conn_test(): | |
20 | + # 数据库连接重试功能和连接超时功能的DB连接 | |
21 | + _conn_status = True | |
22 | + _max_retries_count = 3 # 设置最大重试次数 | |
23 | + _conn_retries_count = 0 # 初始重试次数 | |
24 | + _conn_timeout = 3 # 连接超时时间为3秒 | |
25 | + while _conn_status and _conn_retries_count < _max_retries_count: | |
26 | + try: | |
27 | + print('连接数据库中..') | |
28 | + db = pymysql.connect(host=dbhost, | |
29 | + port=dbport, | |
30 | + user=dbuser, | |
31 | + passwd=dbpassword, | |
32 | + database=dbname, | |
33 | + charset='utf8', | |
34 | + connect_timeout=_conn_timeout) | |
35 | + _conn_status = False # 如果conn成功则_status为设置为False则退出循环,返回db连接对象 | |
36 | + print("连接结果 ",db) | |
37 | + return db | |
38 | + except: | |
39 | + _conn_retries_count += 1 | |
40 | + print(_conn_retries_count) | |
41 | + print('connect db is error!!') | |
42 | + time.sleep(3) # 此为测试看效果 | |
43 | + continue | |
44 | + raise Exception("pls check your mysql config!") | |
45 | + | |
46 | + | |
47 | +def mysql_selectOne(select_action): | |
48 | + action=select_action | |
49 | + db = pymysql.connect(host=dbhost, | |
50 | + port=dbport, | |
51 | + user=dbuser, | |
52 | + passwd=dbpassword, | |
53 | + database=dbname, | |
54 | + charset='utf8', | |
55 | + connect_timeout=3) | |
56 | + cursor = db.cursor() | |
57 | + try: | |
58 | + # 使用execute方法执行SQL语句 | |
59 | + cursor.execute(action) | |
60 | + data = cursor.fetchone() | |
61 | + return data | |
62 | + except Exception as e: | |
63 | + print("数据库操作异常:%s" % str(e)) | |
64 | + log.error("数据库操作异常:%s" % str(e)) | |
65 | + assert False | |
66 | + finally: | |
67 | + # 关闭数据库连接 | |
68 | + db.close() | |
69 | + | |
70 | +def mysql_selectAll(select_action): | |
71 | + action=select_action | |
72 | + db = pymysql.connect(host=dbhost, | |
73 | + port=dbport, | |
74 | + user=dbuser, | |
75 | + passwd=dbpassword, | |
76 | + database=dbname, | |
77 | + charset='utf8', | |
78 | + connect_timeout=3) | |
79 | + cursor = db.cursor() | |
80 | + try: | |
81 | + # 使用execute方法执行SQL语句 | |
82 | + cursor.execute(action) | |
83 | + # 使用 fetchall() 方法获取所有数据 | |
84 | + data = cursor.fetchall() | |
85 | +# print data | |
86 | + return data | |
87 | + except Exception as e: | |
88 | + print("数据库操作异常:%s" % str(e)) | |
89 | + log.error("数据库操作异常:%s" % str(e)) | |
90 | + assert False | |
91 | + finally: | |
92 | + # 关闭数据库连接 | |
93 | + db.close() | |
94 | + | |
95 | +def mysql_delete(delete_action): | |
96 | + action=delete_action | |
97 | + db = pymysql.connect(host=dbhost, | |
98 | + port=dbport, | |
99 | + user=dbuser, | |
100 | + passwd=dbpassword, | |
101 | + database=dbname, | |
102 | + charset='utf8', | |
103 | + connect_timeout=3) | |
104 | + cursor = db.cursor() | |
105 | + try: | |
106 | + # 使用execute方法执行SQL语句 | |
107 | + cursor.execute(action) | |
108 | + # 提交 | |
109 | + db.commit() | |
110 | + except Exception as e: | |
111 | + print("数据库操作异常:%s" % str(e)) | |
112 | + log.error("数据库操作异常:%s" % str(e)) | |
113 | + # 错误回滚 | |
114 | + db.rollback() | |
115 | + finally: | |
116 | + # 关闭数据库连接 | |
117 | + db.close() | |
118 | + | |
119 | +def mysql_update(update_action): | |
120 | + action=update_action | |
121 | + db = pymysql.connect(host=dbhost, | |
122 | + port=dbport, | |
123 | + user=dbuser, | |
124 | + passwd=dbpassword, | |
125 | + database=dbname, | |
126 | + charset='utf8', | |
127 | + connect_timeout=3) | |
128 | + cursor = db.cursor() | |
129 | + try: | |
130 | + # 使用execute方法执行SQL语句 | |
131 | + cursor.execute(action) | |
132 | + # 提交 | |
133 | + db.commit() | |
134 | + except Exception as e: | |
135 | + print("数据库操作异常:%s" % str(e)) | |
136 | + log.error("数据库操作异常:%s" % str(e)) | |
137 | + # 错误回滚 | |
138 | + db.rollback() | |
139 | + finally: | |
140 | + # 关闭数据库连接 | |
141 | + db.close() | |
142 | + | |
143 | +def mysql_insert(insert_action): | |
144 | + action=insert_action | |
145 | + db = pymysql.connect(host=dbhost, | |
146 | + port=dbport, | |
147 | + user=dbuser, | |
148 | + passwd=dbpassword, | |
149 | + database=dbname, | |
150 | + charset='utf8', | |
151 | + connect_timeout=3) | |
152 | + cursor = db.cursor() | |
153 | + try: | |
154 | + # 使用execute方法执行SQL语句 | |
155 | + cursor.execute(action) | |
156 | + # 提交 | |
157 | + db.commit() | |
158 | + except Exception as e: | |
159 | + print("数据库操作异常:%s" % str(e)) | |
160 | + log.error("数据库操作异常:%s" % str(e)) | |
161 | + # 错误回滚 | |
162 | + db.rollback() | |
163 | + finally: | |
164 | + # 关闭数据库连接 | |
165 | + db.close() | |
166 | + | |
167 | +def mysql_check_insert(api,section,check_sql,delete_sql,insert_sql): | |
168 | + log.info(u"======测试数据准备======") | |
169 | + check=ca.get_api_config(api, section, check_sql) | |
170 | + delete=ca.get_api_config(api, section, delete_sql) | |
171 | + insert=ca.get_api_config(api, section, insert_sql) | |
172 | + | |
173 | + try: | |
174 | + db = pymysql.connect(dbhost, dbuser, dbpassword, dbname, charset='utf8' ) | |
175 | + cursor = db.cursor() | |
176 | + # 使用execute方法执行SQL语句 | |
177 | + cursor.execute(check) | |
178 | + result=cursor.fetchall() | |
179 | + # 提交 | |
180 | + db.commit() | |
181 | + if result: | |
182 | + log.info(u"检查到数据库有重复数据%r"%str(result)) | |
183 | + log.info(u"删除查询到的重复数据%r"%str(delete)) | |
184 | + cursor.execute(delete) | |
185 | + log.info(u"删除数据完成") | |
186 | + log.info(u"向数据库中插入测试数据%r"%str(insert)) | |
187 | + cursor.execute(insert) | |
188 | + log.info(u"插入数据完成") | |
189 | + result=cursor.fetchall() | |
190 | + db.commit() | |
191 | + return result | |
192 | + else: | |
193 | + log.info(u"数据库没有重复数据直接插入自定义数据%r"%str(insert)) | |
194 | + result=cursor.execute(insert) | |
195 | + log.info(u"插入数据完成,返回结果为为%r"%str(result)) | |
196 | +# cursor.fetchall() | |
197 | + db.commit() | |
198 | + return result | |
199 | + | |
200 | + except Exception as e: | |
201 | + print(u"数据库操作异常:%r" % str(e)) | |
202 | + log.error(u"数据库操作异常:%r" % str(e)) | |
203 | + # 错误回滚 | |
204 | + db.rollback() | |
205 | + assert False | |
206 | + finally: | |
207 | + # 关闭数据库连接 | |
208 | + db.close() | |
209 | + | |
210 | +def Check_in_Mysql(in_data,sql_spm): | |
211 | + log.info(u"======从数据库中查询传入数据======") | |
212 | + result=mysql_selectAll(sql_spm) | |
213 | + log.info(u"传入in_data为: %s"%in_data) | |
214 | + log.info(u"数据库查询到的结果为 %s"%result) | |
215 | + | |
216 | + result=str(result) | |
217 | + if len(str(in_data)) == 0 and len(result)!=0: | |
218 | + log.error(u"传入数据为空!!\n") | |
219 | + assert False | |
220 | + return | |
221 | + elif len(str(in_data)) == 0 and len(result)==0: | |
222 | + log.error(u"传入数据与数据库查询结果都为空!!\n") | |
223 | + assert False | |
224 | + return | |
225 | + elif len(str(in_data)) != 0 and len(result)==0: | |
226 | + log.error(u"数据库查询结果为空\n") | |
227 | + assert False | |
228 | + return | |
229 | + elif isinstance(in_data,(list)): | |
230 | + log.info(u'检查的数据格式 为list类型') | |
231 | + for i in range(0,len(in_data)): | |
232 | + in_data[i]=str(in_data[i]).decode("utf-8").encode("unicode-escape") | |
233 | + | |
234 | + if in_data[i] in result: | |
235 | + assert True | |
236 | + log.info(u"遍历list第%d次,插入数据%r与数据库查询结果一致"%(i,in_data[i])) | |
237 | + else: | |
238 | + log.error(u"#########ERROR#########:\n in_data与数据库查询结果不一致%r"%in_data[i]) | |
239 | + assert False | |
240 | + return True | |
241 | + | |
242 | + elif str(in_data).decode("utf-8").encode("unicode-escape") in result: | |
243 | + assert True | |
244 | + log.info(u"in_data与数据库查询结果一致!!%r"%in_data) | |
245 | + return True | |
246 | + else: | |
247 | + log.info(u"#########ERROR#########:\n in_data与数据库查询结果不一致!!%r"%in_data) | |
248 | + assert False | |
249 | + | |
250 | +def Check_in_Response(check_data,src_data): | |
251 | + "check_data必须为列表形式,src_data必须为r.json()的数据类型" | |
252 | + log.info(u"======从响应Body中查询传入数据======") | |
253 | + src_data=json.dumps(src_data) | |
254 | + src_data=src_data.replace(" ","") | |
255 | + log.info(u"传入check_data为: %s"%check_data) | |
256 | + log.info(u"对比的响应数据为 %s"%src_data) | |
257 | + if len(check_data) == 0 or len(src_data)==0: | |
258 | + log.error(u"传入数据为空!!\n") | |
259 | + assert False | |
260 | + return | |
261 | + elif isinstance (check_data,str) : | |
262 | + check_data=check_data.replace(" ","").replace("[","").replace("]","").decode("utf-8").split(",") | |
263 | + for i in range(0,len(check_data)): | |
264 | + #由于数据库查询的数据中,中文的格式为unicode-escape,所以传入的数据需要进行encode | |
265 | + check_data[i]=check_data[i].decode("utf-8").encode("unicode-escape") | |
266 | +# print type(check_data),check_data[i] | |
267 | + if check_data[i] in src_data: | |
268 | + assert True | |
269 | + log.info(u"遍历list第%d次,字段%s在请求响应结果中"%((i+1),check_data[i].decode("unicode-escape"))) | |
270 | + else: | |
271 | + log.error(u"#########ERROR#########:\n check_data不在请求响应结果中%s"%check_data[i].decode("unicode-escape")) | |
272 | + assert False | |
273 | + return True | |
274 | + elif isinstance (check_data,list) and len(check_data) > 0: | |
275 | + for i in range(0,len(check_data)): | |
276 | + check_data[i]=check_data[i].decode("utf-8").encode("unicode-escape") | |
277 | + print(type(check_data),check_data[i],str(check_data[i])) | |
278 | + print(type(src_data),src_data) | |
279 | + if check_data[i] in src_data: | |
280 | + assert True | |
281 | + log.info(u"遍历list第%d次,插入数据%r与数据库查询结果一致"%(i,check_data[i])) | |
282 | + else: | |
283 | + log.error(u"#########ERROR#########:\n check_data数据库查询结果不一致%r"%check_data[i]) | |
284 | + assert False | |
285 | + return True | |
286 | + else: | |
287 | + log.info(u"#########ERROR#########:\n 检查数据有问题,请检查!!!!!%r") | |
288 | + assert False | ... | ... |
commons/Faker.py
0 → 100644
1 | +#!/usr/bin/python | |
2 | +# -*- coding: UTF-8 -*- | |
3 | +import random | |
4 | +from faker import Factory | |
5 | + | |
6 | +class random_data(): | |
7 | + | |
8 | + def __init__(self, type='zh_CN'): | |
9 | + self.type = type | |
10 | + self.fake = Factory().create(self.type) | |
11 | + | |
12 | + def date(self): | |
13 | + "随机时间" | |
14 | + return self.fake.date(pattern="%Y-%m-%d") | |
15 | + | |
16 | + def name(self): | |
17 | + "随机姓名" | |
18 | + return self.fake.name() | |
19 | + | |
20 | + def identity_card(self): | |
21 | + "随机姓名" | |
22 | + return self.fake.ssn(min_age=18, max_age=90) | |
23 | + | |
24 | + def plate(self): | |
25 | + "随机车牌号" | |
26 | + return self.fake.license_plate() | |
27 | + | |
28 | + def plate_cn(self,plate_len=6): | |
29 | + char0='京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽赣粤青藏川宁琼' | |
30 | + char1='ABCDEFGHJKLMNPQRSTUVWXYZ'#车牌号中没有I和O,可自行百度 | |
31 | + char2='1234567890' | |
32 | + len0=len(char0)-1 | |
33 | + len1 = len(char1) - 1 | |
34 | + len2 = len(char2) - 1 | |
35 | + ######## | |
36 | + code = '' | |
37 | + index0 = random.randint(0,len0 ) | |
38 | + index1 = random.randint(0,len1) | |
39 | + code += char0[index0] | |
40 | + code += char1[index1] | |
41 | + for i in range(0, plate_len-1): | |
42 | + index2 = random.randint(1, len2) | |
43 | + code += char2[index2] | |
44 | + return(code) | |
45 | + | |
46 | + def country(self): | |
47 | + "随机国家代码" | |
48 | + return self.fake.country() | |
49 | + | |
50 | + def province(self): | |
51 | + "随机省份" | |
52 | + return self.fake.province() | |
53 | + | |
54 | + def city(self): | |
55 | + "随机城市" | |
56 | + return self.fake.city_suffix() | |
57 | + | |
58 | + def district(self): | |
59 | + "随机街道" | |
60 | + return self.fake.district() | |
61 | + | |
62 | + def address(self): | |
63 | + "随机地址全称" | |
64 | + return self.fake.address() | |
65 | + | |
66 | + def phone_number(self): | |
67 | + "随机手机号" | |
68 | + return self.fake.phone_number() | |
69 | + | |
70 | + def email(self): | |
71 | + "随机邮件" | |
72 | + return self.fake.email() | |
73 | + | |
74 | + def longitude(self): | |
75 | + "随机经度" | |
76 | + return self.fake.longitude() | |
77 | + | |
78 | + def latitude (self): | |
79 | + "随机维度" | |
80 | + return self.fake.latitude () | |
81 | + | |
82 | + def credit_card_number (self): | |
83 | + "随机卡号" | |
84 | + return self.fake.credit_card_number () | |
85 | + | |
86 | + | |
87 | + | |
88 | +a=random_data() | |
89 | +print(a.date()) | |
90 | +print(a.name()) | |
91 | +print(a.identity_card()) | |
92 | +print(a.plate()) | |
93 | +print(a.plate_cn(6)) | |
94 | +print(a.country()) | |
95 | +print(a.province()) | |
96 | +print(a.city()) | |
97 | +print(a.district()) | |
98 | +print(a.address()) | |
99 | +print(a.phone_number()) | |
100 | +print(a.email()) | |
101 | +print(a.longitude()) | |
102 | +print(a.latitude()) | |
103 | +print(a.credit_card_number()) | |
104 | + | ... | ... |
commons/Logging.py
0 → 100644
1 | +#!/usr/bin/python | |
2 | +# -*- coding: UTF-8 -*- | |
3 | +import logging,os | |
4 | + | |
5 | +class Logger(): | |
6 | + | |
7 | + def __init__(self, path=__name__,clevel = logging.ERROR,Flevel = logging.DEBUG,test = 'w'): | |
8 | + current_path=os.path.dirname(os.path.dirname(__file__)) | |
9 | + path=current_path+"/report"+"/test.log" | |
10 | + | |
11 | + self.logger = logging.getLogger(path) | |
12 | + | |
13 | + self.logger.setLevel(logging.DEBUG) | |
14 | + | |
15 | + fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] : %(message)s', '%Y-%m-%d %H:%M:%S') | |
16 | + | |
17 | + sh = logging.StreamHandler() | |
18 | + | |
19 | + sh.setFormatter(fmt) | |
20 | + | |
21 | + sh.setLevel(clevel) | |
22 | + | |
23 | + #设置文件日志 | |
24 | + | |
25 | + fh = logging.FileHandler(path,mode=test,encoding="utf-8") | |
26 | + | |
27 | + fh.setFormatter(fmt) | |
28 | + | |
29 | + fh.setLevel(Flevel) | |
30 | + | |
31 | + self.logger.addHandler(sh) | |
32 | + | |
33 | + self.logger.addHandler(fh) | |
34 | + | |
35 | + | |
36 | + def debug(self,message): | |
37 | + | |
38 | + self.logger.debug(message) | |
39 | + | |
40 | + def info(self,message): | |
41 | + | |
42 | + self.logger.info(message) | |
43 | + | |
44 | + | |
45 | + def warn(self,message): | |
46 | + | |
47 | + self.logger.warn(message) | |
48 | + | |
49 | + | |
50 | + def error(self,message): | |
51 | + | |
52 | + self.logger.error(message) | |
53 | + | |
54 | + | |
55 | + def critical(self,message): | |
56 | + | |
57 | + self.logger.critical(message) | ... | ... |
commons/MySession.py
0 → 100644
1 | +#!/usr/bin/python | |
2 | +# -*- coding: UTF-8 -*- | |
3 | +import requests | |
4 | +import json | |
5 | +from commons import common as com | |
6 | +from commons.Logging import Logger | |
7 | +from commons.clientSession import cliSession | |
8 | +log=Logger() | |
9 | + | |
10 | +class mysession(): | |
11 | + "封装了requests的基类,以供后期统一使用" | |
12 | + | |
13 | + url="http://test.uap.diligrp.com/login/login.action" | |
14 | + header={ | |
15 | + "Host": "test.uap.diligrp.com", | |
16 | + "Connection": "keep-alive", | |
17 | + "Content-Length": "33", | |
18 | + "Cache-Control": "max-age=0", | |
19 | + "Upgrade-Insecure-Requests": "1", | |
20 | + "Origin": "http://test.uap.diligrp.com", | |
21 | + "Content-Type": "application/x-www-form-urlencoded", | |
22 | + "User-Agent": "Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/90.0.4430.212Safari/537.36", | |
23 | + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", | |
24 | + "Referer": "http://test.uap.diligrp.com/login/index.html", | |
25 | + "Accept-Encoding": "gzip,deflate", | |
26 | + "Accept-Language": "zh-CN,zh-TW;q=0.9,zh;q=0.8,en;q=0.7", | |
27 | + "Cookie": "UAP_accessToken=;UAP_refreshToken=;UAP_loginPath="} | |
28 | + body="userName=sg_wenze&password=111111" | |
29 | + | |
30 | + def __init__(self): | |
31 | + "如下代码,可以通过配置文件来控制测试环境和灰度环境,http和https" | |
32 | + self.url=mysession.url.replace("http://test.",com.get_global_config("global_data", "environment", "en") ) | |
33 | + self.header=mysession.header | |
34 | + self.body=mysession.body | |
35 | + self.timeout = (5,5) | |
36 | + self.max_retries = 3 | |
37 | + self.keep_alive = False | |
38 | + self.ssl_verify=False | |
39 | + self.proxies=None | |
40 | + self.allow_redirects=False | |
41 | + self.webHeaders,self.clientHeaders,self.userInfo = cliSession().loginUser() | |
42 | + | |
43 | +# self.proxies={'http': 'http://localhost:8888', 'https': 'http://localhost:8888'} | |
44 | + | |
45 | + def get_session(self,account,**kwargs): | |
46 | + "如下代码,可以通过配置文件来控制登录的账户session" | |
47 | + self.body=self.body.replace("sg_wenze", com.get_global_config("global_data", "account", account).split("&")[0]) | |
48 | + self.body=self.body.replace("111111", com.get_global_config("global_data", "account", account).split("&")[1]) | |
49 | + #requests.session()会话保持,比如使用session成功的登录了某个网站, | |
50 | + #则在再次使用该session对象求求该网站的其他网页都会默认使用该session之前使用的cookie等参数 | |
51 | + self.se=requests.session() | |
52 | + #使用session对象的方法POST/GET等 | |
53 | + re=self.se.post(url=self.url, headers=self.header,data=self.body,proxies=self.proxies,**kwargs) | |
54 | + #返回session对象,供其他接口使用 | |
55 | + return self.se | |
56 | + | |
57 | + def close_session(self): | |
58 | + "关闭session" | |
59 | + self.se.close() | |
60 | + | |
61 | + | |
62 | + def check_login(self,account,**kwargs): | |
63 | + "验证登录接口" | |
64 | + self.body=self.body.replace("sg_wenze", com.get_global_config("global_data", "account", account).split("&")[0]) | |
65 | + self.body=self.body.replace("111111", com.get_global_config("global_data", "account", account).split("&")[1]) | |
66 | + #POST请求, | |
67 | + re=self.se.post(url=self.url, headers=self.header,data=self.body,proxies=self.proxies,allow_redirects=False,**kwargs) | |
68 | + #判断请求 | |
69 | + assert "UAP_accessToken" in re.headers["Set-Cookie"] | |
70 | + assert "UAP_refreshToken" in re.headers["Set-Cookie"] | |
71 | + assert "UAP_loginPath" in re.headers["Set-Cookie"] | |
72 | + print("登录接口验证成功") | |
73 | + return re | |
74 | + | |
75 | + def useHeadersRequests(self,method=None,url=None,headers=None,data=None,**kwargs): | |
76 | + """ | |
77 | + 模拟客户端接口操作,使用headers进行cookies传递,调用requests库进行接口访问 | |
78 | + :param method:接口请求方式,POST,GET等 | |
79 | + :param url:接口路径 | |
80 | + :param data:接口数据 | |
81 | + :kwargs:其他requests.request()支持参数可以直接传递 | |
82 | + """ | |
83 | + print(url) | |
84 | + # print(headers) | |
85 | + print(data) | |
86 | + log.info("{0:=^86}".format('')) | |
87 | + log.info("{}\n{}\n{}\n".format(url,data,kwargs)) | |
88 | + if "gateway" in url: | |
89 | + # 判断接口路径,通过接口路径钟是否包含gateway来判定接口是否是由客户端进行访问,来判定headers使用 | |
90 | + self.clientHeaders = dict(self.clientHeaders,**headers) | |
91 | + res = requests.request(method=method, url=url, data=data, headers=self.clientHeaders, **kwargs) | |
92 | + else: | |
93 | + self.webHeaders = dict(self.webHeaders, **headers) | |
94 | + res = requests.request(method=method, url=url, data=data, headers=self.webHeaders, **kwargs) | |
95 | + return res | |
96 | + | |
97 | + | |
98 | + | |
99 | + def get(self, url, **kwargs): | |
100 | + """Sends a GET request. Returns :class:`Response` object. | |
101 | + | |
102 | + :param url: URL for the new :class:`Request` object. | |
103 | + :param \*\*kwargs: Optional arguments that ``request`` takes. | |
104 | + :rtype: requests.Response | |
105 | + """ | |
106 | + #记录日志 | |
107 | + log.info("{0:=^86}".format('')) | |
108 | + log.info("{}\n{}\n".format(url,kwargs)) | |
109 | + #进行请求 | |
110 | + re=self.se.get(url,**kwargs,proxies=self.proxies,timeout=self.timeout) | |
111 | + return re | |
112 | + | |
113 | + def post(self, url, data=None, json=None, **kwargs): | |
114 | + """Sends a POST request. Returns :class:`Response` object. | |
115 | + :param url: URL for the new :class:`Request` object. | |
116 | + :param data: (optional) Dictionary, list of tuples, bytes, or file-like | |
117 | + object to send in the body of the :class:`Request`. | |
118 | + :param json: (optional) json to send in the body of the :class:`Request`. | |
119 | + :param \*\*kwargs: Optional arguments that ``request`` takes. | |
120 | + :rtype: requests.Response | |
121 | + """ | |
122 | + #记录日志 | |
123 | + log.info("{0:=^86}".format('')) | |
124 | + log.info("{}\n{}\n{}\n{}".format(url,data,json,kwargs)) | |
125 | + #进行请求 | |
126 | + re=self.se.post(url, data=data, json=json,proxies=self.proxies, **kwargs,timeout=self.timeout) | |
127 | + return re | |
128 | + | |
129 | + def options(self, url, **kwargs): | |
130 | + """Sends a OPTIONS request. Returns :class:`Response` object. | |
131 | + :param url: URL for the new :class:`Request` object. | |
132 | + :param \*\*kwargs: Optional arguments that ``request`` takes. | |
133 | + :rtype: requests.Response | |
134 | + """ | |
135 | + #记录日志 | |
136 | + log.info(url,kwargs) | |
137 | + #进行请求 | |
138 | + re=self.se.options(url,**kwargs) | |
139 | + return re | |
140 | + | |
141 | + def head(self, url, **kwargs): | |
142 | + """Sends a HEAD request. Returns :class:`Response` object. | |
143 | + | |
144 | + :param url: URL for the new :class:`Request` object. | |
145 | + :param \*\*kwargs: Optional arguments that ``request`` takes. | |
146 | + :rtype: requests.Response | |
147 | + """ | |
148 | + #记录日志 | |
149 | + log.info(url,kwargs) | |
150 | + #进行请求 | |
151 | + re=self.se.head(url,**kwargs) | |
152 | + return re | |
153 | + | |
154 | + def put(self, url, data=None, **kwargs): | |
155 | + """Sends a PUT request. Returns :class:`Response` object. | |
156 | + :param url: URL for the new :class:`Request` object. | |
157 | + :param data: (optional) Dictionary, list of tuples, bytes, or file-like | |
158 | + object to send in the body of the :class:`Request`. | |
159 | + :param \*\*kwargs: Optional arguments that ``request`` takes. | |
160 | + :rtype: requests.Response | |
161 | + """ | |
162 | + #记录日志 | |
163 | + log.info(url,data,kwargs) | |
164 | + #进行请求 | |
165 | + re=self.se.put(url, data,**kwargs) | |
166 | + return re | |
167 | + | |
168 | + def delete(self, url, **kwargs): | |
169 | + """Sends a DELETE request. Returns :class:`Response` object. | |
170 | + :param url: URL for the new :class:`Request` object. | |
171 | + :param \*\*kwargs: Optional arguments that ``request`` takes. | |
172 | + :rtype: requests.Response | |
173 | + """ | |
174 | + #记录日志 | |
175 | + log.info(url,kwargs) | |
176 | + #进行请求 | |
177 | + re=self.se.delete(url,**kwargs) | |
178 | + return re | |
179 | + | |
180 | + def set_mark(self): | |
181 | + "用户自定义优先级方法" | |
182 | + mark_list=eval(com.get_global_config("global_data","mark","list")) | |
183 | + print("预设运行标记:",mark_list) | |
184 | + global _global_mark | |
185 | + if type(mark_list)==type([]) and len(mark_list)!=0 : | |
186 | + _global_mark=mark_list | |
187 | + return _global_mark | |
188 | + elif type(mark_list)==type([]) and len(mark_list)==0: | |
189 | + _global_mark=False | |
190 | + return _global_mark | |
191 | + else: | |
192 | + raise Exception("error,pls check mark data") | |
193 | + | |
194 | + def mark(self,m=None): | |
195 | + try: | |
196 | + #没有输入任何预设值,默认跑全部 | |
197 | + if _global_mark == False : | |
198 | + return True | |
199 | + #输入预设值且未标记用例,默认跑全部 | |
200 | + elif _global_mark != False and (m in _global_mark): | |
201 | + return True | |
202 | + else: | |
203 | + return False | |
204 | + except Exception as e: | |
205 | + return False | |
206 | + | |
207 | + | |
208 | + | |
209 | +my=mysession() | |
210 | +my.set_mark() | |
211 | +s1=my.get_session("user01") | |
212 | +# s2=my.get_session("user02") | ... | ... |
commons/SendEmail.py
0 → 100644
1 | +#!/usr/bin/python | |
2 | +# -*- coding: UTF-8 -*- | |
3 | +import os | |
4 | +import smtplib | |
5 | +from email.mime.multipart import MIMEMultipart | |
6 | +from email.header import Header | |
7 | +from email.mime.text import MIMEText | |
8 | +from email.mime.image import MIMEImage | |
9 | +from email.mime.application import MIMEApplication | |
10 | +from commons.Logging import Logger | |
11 | +log=Logger() | |
12 | + | |
13 | +def send_email_text(): | |
14 | + # 1. 编写邮件内容(Email邮件需要专门的MIME格式) | |
15 | + msg = MIMEText('this is a test email', 'plain', 'utf-8') | |
16 | + | |
17 | + # 2. 组装Email头(发件人,收件人,主题) | |
18 | + msg['From'] = 'autotest@diligrp.com' # 发件人 | |
19 | + msg['To'] = 'lixi@diligrp.com' # 收件人 | |
20 | + msg['Subject'] = 'Api Test Report' # 邮件主题 | |
21 | + | |
22 | + # 3. 连接smtp服务器并发送邮件 | |
23 | + smtp = smtplib.SMTP_SSL('smtp.exmail.qq.com') | |
24 | + smtp.login('autotest@diligrp.com', 'MvkuGGCfMtAdbJvE') | |
25 | + smtp.sendmail("autotest@diligrp.com", "lixi@diligrp.com", msg.as_string()) | |
26 | + smtp.quit() | |
27 | + | |
28 | + | |
29 | +def send_email(send_file,send_to=["lixi@diligrp.com"]): | |
30 | + | |
31 | + log_path=os.path.dirname(os.path.dirname(__file__)) | |
32 | + log_path=log_path+"/report/test.log" | |
33 | + send_msg=(",".join(str(i) for i in send_to)) | |
34 | + msg = MIMEMultipart() # 混合MIME格式 | |
35 | + msg['From'] = 'autotest@diligrp.com' # 发件人 | |
36 | + msg['To'] = send_msg # 收件人 | |
37 | + msg['Subject'] = Header('接口测试报告', 'utf-8') # 中文邮件主题,指定utf-8编码 | |
38 | + | |
39 | + text = MIMEText('this is a test email', 'plain', 'utf-8') | |
40 | + msg.attach(MIMEText(open(send_file,'rb' ).read(), 'html', 'utf-8')) | |
41 | + | |
42 | + att1 = MIMEText(open(send_file, 'rb').read(), 'base64', 'utf-8') | |
43 | + att1["Content-Disposition"] = 'attachment; filename="report.html"' | |
44 | + | |
45 | + att2 = MIMEText(open(log_path, 'rb').read(), 'base64', 'utf-8') | |
46 | + att2["Content-Type"] = 'application/octet-stream' | |
47 | + att2["Content-Disposition"] = 'attachment; filename="test.log"' | |
48 | + msg.attach(text) | |
49 | + msg.attach(att1) | |
50 | + msg.attach(att2) | |
51 | + | |
52 | + #一下发送日志不会在test.log上,因为提前msg.attach了 | |
53 | + log.info("发送邮件") | |
54 | + try: | |
55 | + smtp = smtplib.SMTP_SSL('smtp.exmail.qq.com') # smtp服务器地址 使用SSL模式 | |
56 | + re=smtp.login('autotest@diligrp.com', 'MvkuGGCfMtAdbJvE') # 用户名和密码 | |
57 | + smtp.sendmail("autotest@diligrp.com", send_to, msg.as_string()) | |
58 | + print(re) | |
59 | + except Exception as e: | |
60 | + log.error(str(e)) | |
61 | + print(e) | |
62 | + finally: | |
63 | + smtp.quit() | |
64 | + log.info("邮件发送完毕") | ... | ... |
commons/__init__.py
0 → 100644
commons/api/__init__.py
0 → 100644
commons/clientSession.py
0 → 100644
1 | +# -*- coding: utf-8 -*- | |
2 | + | |
3 | +# @Time : 2021/7/16 10:23 | |
4 | +# @Author : Ljq | |
5 | +# @File : clientSession.py | |
6 | +# @Software: PyCharm | |
7 | + | |
8 | +""" | |
9 | + | |
10 | +""" | |
11 | + | |
12 | +import requests | |
13 | +import json | |
14 | +from src.commons.readConf import readConfig | |
15 | + | |
16 | +class cliSession(object): | |
17 | + def __init__(self): | |
18 | + rConf = readConfig() | |
19 | + | |
20 | + def __init__(self): | |
21 | + rC = readConfig() | |
22 | + self.userName = rC.returnOptionsItems("loginInfo","userName") | |
23 | + self.password = rC.returnOptionsItems("loginInfo","password") | |
24 | + self.loginUrl = rC.returnOptionsItems("host","uapHost")+"/api/authenticationApi/loginWeb" | |
25 | + self.loginData = {"userName":self.userName,"password":self.password} | |
26 | + self.webHeaders = {"X-Requested-With":"XMLHttpRequest", | |
27 | + "Content-Type":"application/x-www-form-urlencoded", | |
28 | + "Cookie":"UAP_accessToken=${UAP_accessToken}; UAP_refreshToken=${UAP_refreshToken};UAP_firmId=${UAP_firmId}"} | |
29 | + | |
30 | + self.clientHeaders={"UAP_accessToken":"${UAP_accessToken}", | |
31 | + "UAP_refreshToken":"${UAP_refreshToken}", | |
32 | + "UAP_firmId":"${UAP_firmId}", | |
33 | + "Cookie":"UAP_accessToken=${UAP_accessToken}; UAP_refreshToken=${UAP_refreshToken}", | |
34 | + "Content-Type":"application/json"} | |
35 | + | |
36 | + def loginUser(self): | |
37 | + """ | |
38 | + | |
39 | + :return: | |
40 | + """ | |
41 | + # 返回登录信息,以及可用headers,clientHeaders用户客户端操作header,webHeaders用于web页面使用headers | |
42 | + res = requests.post(url=self.loginUrl,data=json.dumps(self.loginData)) | |
43 | + print(res.json()) | |
44 | + UAP_accessToken,UAP_refreshToken,UAP_firmId=res.json()["data"]["accessToken"],res.json()["data"]["refreshToken"],res.json()["data"]["user"]["firmId"] | |
45 | + webHeadersCookie = "UAP_accessToken="+UAP_accessToken+"; UAP_refreshToken="+UAP_refreshToken+";UAP_firmId="+str(UAP_firmId) | |
46 | + clientHeadersCookie = "UAP_accessToken="+UAP_accessToken+"; UAP_refreshToken="+UAP_refreshToken | |
47 | + self.webHeaders["Cookie"] = webHeadersCookie | |
48 | + self.clientHeaders["UAP_accessToken"] = UAP_accessToken | |
49 | + self.clientHeaders["UAP_refreshToken"]= UAP_refreshToken | |
50 | + self.clientHeaders["UAP_firmId"] = str(UAP_firmId) | |
51 | + self.clientHeaders["Cookie"] = clientHeadersCookie | |
52 | + return self.webHeaders,self.clientHeaders,res.json() | ... | ... |
commons/common.py
0 → 100644
1 | +#!/usr/bin/python | |
2 | +# -*- coding: UTF-8 -*- | |
3 | +import os | |
4 | +import configparser | |
5 | +import unittest | |
6 | +from discover import DiscoveringTestLoader | |
7 | +from commons.Logging import Logger | |
8 | +log=Logger() | |
9 | + | |
10 | + | |
11 | +def get_global_config(file,section, key): | |
12 | + "object file is *src/config/global_data.conf" | |
13 | + current_path=os.path.dirname(__file__) | |
14 | + src_path=os.path.dirname(current_path) | |
15 | +# global_setting_path=src_path+'/config/global_data.conf' | |
16 | + global_setting_path=src_path+'/config/'+file+".conf" | |
17 | + #验证文件是否存在 | |
18 | + file_path = os.path.exists(global_setting_path) | |
19 | + if file_path: | |
20 | + #获取文件的数据 | |
21 | + if isinstance(key,int): | |
22 | + log.error("key of section cannot be int Type :<%r> "%str(key)) | |
23 | + raise Exception("key of section cannot be int Type :<%r> "%str(key)) | |
24 | + else: | |
25 | + config = configparser.ConfigParser() | |
26 | + config.read(global_setting_path,encoding="utf-8") | |
27 | + return config.get(section, key) | |
28 | + else: | |
29 | + log.error("File Not Exist :<%r> "%str(global_setting_path)) | |
30 | + raise Exception("File Not Exist :<%r> "%str(global_setting_path)) | |
31 | + | |
32 | + | |
33 | +def get_api_config(api,section,key): | |
34 | + "object file is *src/config/api/*.conf" | |
35 | + current_path=os.path.dirname(__file__) | |
36 | + src_path=os.path.dirname(current_path) | |
37 | + api_path=src_path+"/config/api/" | |
38 | + api_config_path=api_path+api+".conf" | |
39 | + #验证文件是否存在 | |
40 | + file_path = os.path.exists(api_config_path) | |
41 | + if file_path: | |
42 | + #获取文件的数据 | |
43 | + if isinstance(key,int): | |
44 | + log.error("key of section cannot be int Type :<%r> "%str(key)) | |
45 | + raise Exception("key of section cannot be int Type :<%r> "%str(key)) | |
46 | + else: | |
47 | + config = configparser.ConfigParser() | |
48 | + config.read(api_config_path,encoding="utf-8") | |
49 | + return config.get(section, key) | |
50 | + else: | |
51 | + log.error("File Not Exist :<%r> "%str(api_config_path)) | |
52 | + raise Exception("File Not Exist :<%r> "%str(api_config_path)) | |
53 | + | |
54 | + | |
55 | +def run_one(name): | |
56 | + test_suite = unittest.TestSuite() | |
57 | + #创建测试套 | |
58 | + test_suite.addTest(name) | |
59 | + #显示运行用例 | |
60 | + print("运行用例为{}".format(test_suite)) | |
61 | + runner = unittest.TextTestRunner() | |
62 | + runner.run(test_suite) | |
63 | + | |
64 | +def run_list(name): | |
65 | + test_suite = unittest.TestSuite() | |
66 | + test_suite.addTests(name) | |
67 | + #显示运行用例 | |
68 | + print("运行用例为{}".format(test_suite)) | |
69 | + runner = unittest.TextTestRunner() | |
70 | + runner.run(test_suite) | |
71 | + | |
72 | +def run_class(name): | |
73 | + test_cases = unittest.TestLoader().loadTestsFromTestCase(name) | |
74 | + #显示运行用例 | |
75 | + print("运行用例为{}".format(test_cases)) | |
76 | + runner = unittest.TextTestRunner() | |
77 | + runner.run(test_cases) | |
78 | + | |
79 | +def run_Module(name): | |
80 | + test_cases = unittest.TestLoader().loadTestsFromModule(name) | |
81 | + #显示运行用例 | |
82 | + print("运行用例为{}".format(test_cases)) | |
83 | + runner = unittest.TextTestRunner() | |
84 | + runner.run(test_cases) | |
85 | + | |
86 | +def run_Name(name): | |
87 | + test_cases = unittest.TestLoader().loadTestsFromName(name) | |
88 | + #显示运行用例 | |
89 | + print("运行用例为{}".format(test_cases)) | |
90 | + runner = unittest.TextTestRunner() | |
91 | + runner.run(test_cases) | ... | ... |
commons/readConf.py
0 → 100644
1 | +# -*- coding: utf-8 -*- | |
2 | + | |
3 | +# @Time : 2021/7/16 10:36 | |
4 | +# @Author : Ljq | |
5 | +# @File : readConf.py | |
6 | +# @Software: PyCharm | |
7 | + | |
8 | +""" | |
9 | +配置文件读取 | |
10 | +""" | |
11 | + | |
12 | +import configparser | |
13 | +import os | |
14 | + | |
15 | +class readConfig(object): | |
16 | + ROBOT_LIBRARY_SCOPE = 'TEST CASE' | |
17 | + ROBOT_LIBRARY_VERSION = '0.1' | |
18 | + | |
19 | + def __init__(self): | |
20 | + self.conf = configparser.ConfigParser() | |
21 | + self.evn_name = os.name | |
22 | + self.file_name = r'test_config_hg' | |
23 | + if self.evn_name == 'nt': | |
24 | + self.relative_path = r'/config/marketConfig/' | |
25 | + self.file_path = os.path.abspath(os.path.join(os.getcwd(), "../..")) + self.relative_path+self.file_name | |
26 | + elif self.evn_name == 'posix': | |
27 | + self.relative_path = r'/src/config/marketConfig/' | |
28 | + self.file_path = os.path.abspath(os.path.join(os.getcwd())) + self.relative_path + self.file_name | |
29 | + # self.file_path = os.getcwd() | |
30 | + print(self.file_path) | |
31 | + self.conf.read(self.file_path,encoding="utf-8") | |
32 | + | |
33 | + def returnSections(self): | |
34 | + sections = self.conf.sections() | |
35 | + print(sections) | |
36 | + return sections | |
37 | + | |
38 | + def returnOptions(self,options): | |
39 | + options = self.conf.options(options) | |
40 | + print(options) | |
41 | + return options | |
42 | + | |
43 | + def returnOptionsInfo(self,items): | |
44 | + items = self.conf.items(items) | |
45 | + print(items) | |
46 | + | |
47 | + def returnOptionsItems(self,options,items): | |
48 | + value = self.conf.get(options,items) | |
49 | + print(value) | |
50 | + return value | |
51 | + | |
52 | + def ReturnFilePath(self): | |
53 | + print(self.file_path) | |
54 | + return self.file_path | |
55 | + | |
56 | +# readConfig().returnOptionsItems("loginInfo","userName") | |
0 | 57 | \ No newline at end of file | ... | ... |
config/__init__.py
0 → 100644
config/global_data.conf
0 → 100644
1 | +# -*- coding: UTF-8 -*- | |
2 | + | |
3 | +[account] | |
4 | +user01=sg_wenze&111111 | |
5 | +user02=sgwanggang&111111 | |
6 | +user03=hz_wenze&111111 | |
7 | + | |
8 | +[userId] | |
9 | +user01=210 | |
10 | +user02=87 | |
11 | +user03=256 | |
12 | + | |
13 | +[email] | |
14 | +list=["lixi@diligrp.com","175930106@qq.com"] | |
15 | +list11=["tg@diligrp.com","175930106@qq.com"] | |
16 | + | |
17 | +[mark] | |
18 | +list=["test"] | |
19 | +list1=["p1","P2",1,"test"] | |
20 | + | |
21 | +[Database] | |
22 | +dbhost=10.35.100.34 | |
23 | +dbport=3306 | |
24 | +dbname=dili_trace | |
25 | +dbuser=root | |
26 | +dbpassword=123456 | |
27 | +dbcharset=utf8 | |
28 | + | |
29 | +[environment] | |
30 | +en=http://test. | |
31 | + | |
32 | + | |
33 | + | |
34 | + | |
35 | + | |
36 | + | ... | ... |
config/global_data_backup.backup
0 → 100644
1 | +# -*- coding: UTF-8 -*- | |
2 | + | |
3 | +[account] | |
4 | +user01=sg_wenze&111111 | |
5 | +user02=sgwanggang&111111 | |
6 | +user03=hz_wenze&111111 | |
7 | + | |
8 | +[userId] | |
9 | +user01=210 | |
10 | +user02=87 | |
11 | +user03=256 | |
12 | + | |
13 | +[environment] | |
14 | +en=http://test. | |
15 | + | |
16 | +[mark] | |
17 | +list=["test"] | |
18 | +list1=["p1","P2",1,"test"] | |
19 | + | |
20 | +[Database] | |
21 | +dbhost=10.35.100.34 | |
22 | +dbport=3306 | |
23 | +dbname=dili_trace | |
24 | +dbuser=root | |
25 | +dbpassword=123456 | |
26 | +dbcharset=utf8 | |
27 | + | |
28 | +[email] | |
29 | +list=[] | |
30 | +list1=["lixi@diligrp.com","LI@diligrp.com"] | |
31 | + | |
32 | + | |
33 | + | |
34 | + | |
35 | + | |
36 | + | ... | ... |
config/marketConfig/__init__.py
0 → 100644
config/marketConfig/put_market_config_info_here
0 → 100644
config/marketConfig/test_config_hg
0 → 100644
1 | +#沈阳市场信息 | |
2 | +[loginInfo] | |
3 | +userName=sg_wenze | |
4 | +password=mEVEUpWSthCXdmiXetK5TKkBEGr6kxMD0ZeFwinI/cpwC4FGk+TD6GWdKefb062UK69rGzKyLlLTxCzdFpRi1gcrG0m6erXZ+tV1I0GcvCbmQPJfn0Ha828rnbWbXS5eqKa6qOYTgZGO5tOVo0DSKMh9b/cReL7IGJ4/WF2Th8A= | |
5 | + | |
6 | +[testInfo] | |
7 | +#已添加的身份证号 | |
8 | +cCNum= | |
9 | +cCNumB= | |
10 | +#入库未开卡的卡号 | |
11 | +cardNum= | |
12 | +#已开卡的卡号 | |
13 | +cardNumRe= | |
14 | +#密码设置 | |
15 | +loginPwd=111111 | |
16 | + | |
17 | +[host] | |
18 | +cardHost=http://test.card.diligrp.com:8386 | |
19 | +uapHost=http://test.uap.diligrp.com | |
20 | +gatewayHost=http://test.gateway.diligrp.com:8285 | |
0 | 21 | \ No newline at end of file | ... | ... |
demo.py deleted
100644 → 0
report/__init__.py
0 → 100644
report/test.log
0 → 100644
1 | +[2021-07-16 13:26:19] [INFO] : ====================================================================================== | |
2 | +[2021-07-16 13:26:19] [INFO] : http://test.trace.diligrp.com:8393/fieldConfig/doUpdate.action | |
3 | +None | |
4 | +{'moduleType': '1', 'marketId': '8', 'fieldConfigDetailList': [{'fieldName': 'unitPrice', 'jsonPath': '$.unitPrice', 'defaultId': '3', 'displayed': '1', 'required': '0'}, {'fieldName': 'arrivalTallynos', 'jsonPath': '$.arrivalTallynos', 'defaultId': '10', 'displayed': '1', 'required': '0'}, {'fieldName': 'brandName', 'jsonPath': '$.brandName', 'defaultId': '5', 'displayed': '1', 'required': '0'}, {'fieldName': 'truckTareWeight', 'jsonPath': '$.truckTareWeight', 'defaultId': '1', 'displayed': '1', 'required': '0'}, {'fieldName': 'originId', 'jsonPath': '$.originId', 'defaultId': '7', 'displayed': '1', 'required': '0'}, {'fieldName': 'specName', 'jsonPath': '$.specName', 'defaultId': '4', 'displayed': '1', 'required': '0'}, {'fieldName': 'truckType', 'jsonPath': '$.truckType', 'defaultId': '2', 'displayed': '1', 'required': '1', 'availableValueList': ['10', '20']}, {'fieldName': 'imageCertList', 'jsonPath': '$.imageCertList[*]certType', 'defaultId': '11', 'displayed': '1', 'required': '0', 'availableValueList': ['2', '3']}, {'fieldName': 'arrivalDatetime', 'jsonPath': '$.arrivalDatetime', 'defaultId': '9', 'displayed': '1', 'required': '0'}, {'fieldName': 'remark', 'jsonPath': '$.remark', 'defaultId': '8', 'displayed': '1', 'required': '0'}, {'fieldName': 'remark', 'jsonPath': '$.remark', 'defaultId': '6', 'displayed': '1', 'required': '0'}, {'fieldName': 'measureType', 'jsonPath': '$.measureType', 'defaultId': '12', 'displayed': '1', 'required': '1', 'availableValueList': ['10', '20']}]} | |
5 | +{'headers': {'Host': 'test.trace.diligrp.com:8393', 'Connection': 'keep-alive', 'Content-Length': '1378', 'Accept': 'application/json,text/javascript,*/*;q=0.01', 'X-Requested-With': 'XMLHttpRequest', 'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/91.0.4472.77Safari/537.36', 'Content-Type': 'application/json', 'Origin': 'http://test.trace.diligrp.com:8393', 'Referer': 'http://test.trace.diligrp.com:8393/fieldConfig/bill.html', 'Accept-Encoding': 'gzip,deflate', 'Accept-Language': 'zh-CN,zh-TW;q=0.9,zh;q=0.8,en;q=0.7'}} | |
6 | +[2021-07-16 13:26:19] [INFO] : ====================================================================================== | |
7 | +[2021-07-16 13:26:19] [INFO] : http://test.trace.diligrp.com:8393/newRegisterBill/doAdd.action | |
8 | +{"registerHeadWeight": "0", "registerHeadRemainWeight": "0", "imageCertList": [], "measureType": 20, "registType": 10, "userId": 516, "arrivalTallynos": [], "arrivalDatetime": "", "truckType": 10, "weight": "111", "weightUnit": 1, "productName": "\u5927\u767d\u83dc", "productId": 2190, "originName": "", "originId": "", "unitPrice": "", "truckTareWeight": "", "remark": "", "specName": "", "brandName": "", "plate": "\u5dddA123456"} | |
9 | +{} | |
10 | + | |
11 | +[2021-07-16 13:26:20] [INFO] : ====================================================================================== | |
12 | +[2021-07-16 13:26:20] [INFO] : http://test.trace.diligrp.com:8393/newRegisterBill/doAdd.action | |
13 | +{"registerHeadWeight": "0", "registerHeadRemainWeight": "0", "imageCertList": [], "measureType": 20, "registType": 10, "userId": 516, "arrivalTallynos": [], "arrivalDatetime": "", "truckType": 10, "weight": "111", "weightUnit": 1, "productName": "\u5927\u767d\u83dc", "productId": 2190, "originName": "", "originId": "", "unitPrice": "", "truckTareWeight": "", "remark": "", "specName": "", "brandName": "", "plate": "\u5dddA123456"} | |
14 | +{} | |
15 | + | ... | ... |