def request_deal_two(request_data, pressure_test_file): # 请求数据中所有特殊类型的key值列表 special_key, special_key_two, special_key_three = PressureTest.request_deal_one( request_data) f = open(pressure_test_file, "r") # 设置文件对象 param_one = f.read() # 将txt文件的所有内容读入到字符串str中 param = param_one.split('\n') special_one = [] special_two = [] # 每个key赋值相应的值,所有的情况存为一个列表 for i in param: param_two = i.split(' ') # 以一个空格为分隔符,所以文件中数据不能有多个空格 for x in range(len(param_two)): special_key[x] = { str(special_key[x]): param_two[x] } # 对每个key进行赋值,外套循环 special_one.append(special_key[x]) if x == len( param_two) - 1: # 一行数据赋值完毕,对下一行数据再次进行赋值,所以已赋值的数据存入列表内 special_two.append(special_one) # 一行数据处理完后,将special_one和special_key的值都置为初始化的数据,否则在原来的基础上再操作,会出现问题 special_one = [] special_key, special_key_two, special_key_three = PressureTest.request_deal_one( request_data) f.close() # 将文件关闭 # 读取完文件内容后,再对请求数据进行处理,将文件中的内容赋值到请求数据中 request_data = eval(request_data) request_data_list = [] # 一个接口做压测所有需要请求的线程数的请求数据列表 for x in range( len(special_two)): # 相当于循环txt文件中的行数,如10行即代表要10个线程,请求10次接口 for y in range( len(special_key)): # 相当于循环txt文件中的列数,作用是为了给每个请求数据中的相应key赋值 key = special_key[y] request_data[key] = special_two[x][y][key] # 将每个a包含~的参数赋值 for z in special_key_two: # 将每个包含&的参数赋值 # 自定义一个函数如随机函数,将其中的某个值赋给请求数据中的参数 request_data[z] = CommonMethod.custom_random_one( ) # 赋值随机整数 # request_data_temp[i] = CommonMethod.create_phone() # 赋值随机电话号码数(返回的类型是str类型) # param = CommonMethod.random_param_one() # 这里参数是从用户写入到random_param.txt文件中读取的内容 # request_data[i] = CommonMethod.custom_random_two(param) # 列表内的值随机一个赋值给参数值 for k in special_key_three: # 将每个包含*的参数赋值 # 将单独封装处理的接口如登录接口返回值,赋值给请求数据中的参数 response_alone = InterfaceDealAlone.user_login() request_data[k] = CommonMethod.response_alone_deal( response_alone, k) if y == len(special_key) - 1: # 这里需要将请求数据转换为str类型,否则最后存入列表内的值都是最后一个dict的值,且需要将请求数据中的单引号替换为双引号 request_data_list.append( str(request_data).replace("\'", "\"")) return request_data_list
def run_pressure_test(self, test_case_file): test_case_list = [] # 存储测试用例内容的列表 LogPrint().info("----------------开始读取excel中的测试用例----------------") all_list = ExcelDeal().get_test( test_case_file, 'PressureTest') # 将测试用例文件路径参数化,这种可以读取多个测试用例文件 for i in all_list: me = dict(zip(self.param_list, i)) test_case_list.append(me) md = self.md conn = self.conn cur = self.cur LogPrint().info("----------------执行用例前插入准备更新的表记录----------------") sql_one = 'insert into pressure_test_data(success_num, fail_num, error_num, case_total,create_time)' \ ' values (0,0,0,0,now())' md.other_operate_db(conn, cur, sql_one) sql_two = 'select result_id from pressure_test_data order by create_time desc limit 1' result_one = md.select_db(conn, cur, sql_two) result_id = result_one[0][0] LogPrint().info("----------------开始执行测试用例----------------") # 记录测试开始时间 start_time = datetime.datetime.now() PressureTest().run_deal_one(result_id, test_case_list) # 将测试用例执行时间存入到数据库中 time.sleep(0.5) end_time = datetime.datetime.now() start_time, end_time = CommonMethod.test_time_deal( md, conn, cur, start_time, end_time, result_id, 'PressureTest') LogPrint().info("----------------生成测试报告----------------")
def post_deal(self): data = eval(self.request_data) # 将str类型转换成字典类型 payload = json.dumps(data) headers = {'content-type': "application/json"} # headers = InterfaceHeadDeal().sign_headers(payload, self.request_data_type) url = self.api_host + self.request_url LogPrint().info('-------------调用第' + self.num + '个测试用例的接口-------------:' + url) try: response = '' if self.request_data_type in ('Data', 'File'): response = requests.post(url=url, data=payload, headers=headers, timeout=5) elif self.request_data_type == 'Form': # 以form形式发送post请求,只需将请求的参数构造成一个字典,传入给request.post()的data参数即可 response = requests.post(url=url, data=data, timeout=5) status = response.status_code resp1 = response.text if status == 200: resp2 = CommonMethod.response_data_deal(resp1) # 对接口返回的数据进行处理,如结果中存在转义字符需要存储到数据库中,则需要进行数据的相应处理 else: resp2 = resp1 # 如果接口请求是404、415等非正常的状态码,那么返回的数据就不需要进行处理,直接存入数据库中即可 assert_result = self.common_code_one(status, resp2) self.response_last = resp2 return assert_result except Timeout: assert_result = self.common_code_two(url) self.response_last = "null" return assert_result
def assert_deal(self, resp): check_point_list = self.check_point.split(",") check_result_list = [] for i in check_point_list: # check_point中可能需要多个校验的数据,所以要用逗号分隔符对字符串进行切片 if 'code' in i or 'msg' in i: # 这里是判断是否是code和msg断言,前两种是正常和异常的code、msg断言 if i in resp: check_result_list.append(True) else: check_result_list.append(False) else: # 这种情况是接口关键数据断言,校验具体返回的数据字段值 # i必须是'{"openId":"$openId"}'这种格式,这里是对excel中的check_point格式进行了转换,excel中的格式必须是"${openId}>0"这种 i_one = i.split("{") i_two = i_one[1].split("}") i_three = '$' + i_two[0] i_four = str({i_two[0]: i_three}) request_data_last = CommonMethod.request_data_deal(i_four, resp) i_nine = i_two[1] i_ten = i_nine.split("\"")[0] if i_ten[1] != '=' and i_ten[1] != '<' and i_ten[1] != '>': i_five = i_ten[0] # 断言语句中的符号 i_six = i_ten[1:] # 断言语句中的预期数据字段值 else: i_five = i_ten[:2] i_six = i_ten[2:] i_seven = eval(request_data_last) i_eight = i_seven[i_two[0]] # 从resp中拿出来的需要校验的实际数据字段值 if i_five == '>': check_result_list.append(str(i_eight) > str(i_six)) elif i_five == '<': check_result_list.append(str(i_eight) < str(i_six)) elif i_five == '=': check_result_list.append(str(i_eight) == str(i_six)) elif i_five == '>=': check_result_list.append(str(i_eight) >= str(i_six)) elif i_five == '<=': check_result_list.append(str(i_eight) <= str(i_six)) elif i_five == '!=': check_result_list.append(str(i_eight) != str(i_six)) else: LogPrint().info('--------断言语句中的比较符号有误,暂时只支持6种,请核对!---------') if False in check_result_list: self.assert_result = 'fail' else: self.assert_result = 'success'
def run_interface_test(self, test_case_file): test_case_list = [] # 存储测试用例内容的列表 LogPrint().info("----------------开始读取excel中的测试用例----------------") all_list = ExcelDeal().get_test( test_case_file, 'NormalTest') # 将测试用例文件路径参数化,这种可以读取多个测试用例文件 for i in all_list: me = dict(zip(self.param_list, i)) test_case_list.append(me) md = self.md conn = self.conn cur = self.cur LogPrint().info("----------------执行用例前插入准备更新的表记录----------------") sql_one = 'insert into test_result_data(success_num, fail_num, error_num, case_total,create_time)' \ ' values (0,0,0,0,now())' md.other_operate_db(conn, cur, sql_one) sql_two = 'select result_id from test_result_data order by create_time desc limit 1' result_one = md.select_db(conn, cur, sql_two) result_id = result_one[0][0] LogPrint().info("----------------开始执行测试用例----------------") # 记录测试开始时间 start_time = datetime.datetime.now() self.run_test(result_id, test_case_list) # 将测试用例执行时间存入到数据库中 time.sleep(0.5) end_time = datetime.datetime.now() start_time, end_time = CommonMethod.test_time_deal( md, conn, cur, start_time, end_time, result_id, 'NormalTest') LogPrint().info("----------------生成测试报告----------------") filename = HtmlReport().generate_html( md, conn, cur, 'test report', '/Users/hongnaiwu/MyProject/InterfaceFrame/Report/report.html', start_time, end_time) # 这里'r'读模式,'w'写模式,'a'追加模式,'b'二进制模式,'+'读/写模式 fo = open(filename, "r+") text = fo.read() ms = MailSend() # 发送测试报告 ms.send_mail(text)
def run_test2(self, relevance_case, result_id, test_case_list): md = self.md conn = self.conn cur = self.cur for x in range(len(test_case_list)): if int(test_case_list[x]['num']) == int(relevance_case): LogPrint().info("----------先调用被关联的第" + str(relevance_case) + "个测试用例的接口----------") ifd = InterfaceDeal(test_case_list[x]['num'], test_case_list[x]['api_purpose'], test_case_list[x]['request_url'], test_case_list[x]['request_method'], test_case_list[x]['request_data_type'], test_case_list[x]['request_data'], test_case_list[x]['check_point'], test_case_list[x]['test_describe'], test_case_list[x]['relevance_case']) result_temp2, response = ifd.interface_test() LogPrint().info( "----------------根据用例执行情况,开始更新测试结果表的相关数据----------------") if result_temp2 == 'success': CommonMethod.sql_deal_two(md, conn, cur, 'success_num', result_id) elif result_temp2 == 'fail': CommonMethod.sql_deal_two(md, conn, cur, 'fail_num', result_id) elif result_temp2 == 'error': CommonMethod.sql_deal_two(md, conn, cur, 'error_num', result_id) else: LogPrint().info( "----------------更新测试结果表失败,原因未知----------------") return response else: continue
def run_test(self, result_id, test_case_list): check_list = [] # 用来核对某个用例是否已经执行过 md = self.md conn = self.conn cur = self.cur # 该值是interface_test()函数处理完接口,并且断言完毕返回的结果,需要根据该结果更新test_result_data表的内容 result_temp = '' for x in range(len(test_case_list)): # 循环所有的测试用例,先判断该用例是否已执行过,如果不在check_list中,则代表未执行过 if int(test_case_list[x]['num']) not in check_list: # 未执行过的用例,再判断下该用例是否有关联的测试用例,如果测试用例的relevance_case字段值不为0,则代表有关联的用例 if int(test_case_list[x]['relevance_case']) != 0: LogPrint().info("----------开始调用第" + test_case_list[x]['num'] + "个测试用例的接口----------") # 先去执行被关联的测试用例 for y in range(len(test_case_list)): # 如果被关联的测试用例接口未执行过,那么就需要循环到被关联的接口,让它执行一次 if int(test_case_list[x] ['relevance_case']) not in check_list: # 如果已循环到该未执行过的被关联的接口 if int(test_case_list[y]['num']) == int( test_case_list[x]['relevance_case']): # 先执行被关联的接口 result_two = self.run_test2( test_case_list[x]['relevance_case'], result_id, test_case_list) LogPrint().info("----------继续调用第" + test_case_list[x]['num'] + "个测试用例的接口----------") # 执行完毕后将该用例的编号存入到检查列表中,防止再次执行 check_list.append( int(test_case_list[x]['relevance_case'])) # 处理请求接口的数据,将被关联的接口数据赋值给请求的接口数据中 request_data_last = CommonMethod.request_data_deal( test_case_list[x]['request_data'], result_two) ifd = InterfaceDeal( test_case_list[x]['num'], test_case_list[x]['api_purpose'], test_case_list[x]['request_url'], test_case_list[x]['request_method'], test_case_list[x]['request_data_type'], request_data_last, test_case_list[x]['check_point'], test_case_list[x]['test_describe'], test_case_list[x]['relevance_case']) result_temp, response = ifd.interface_test() check_list.append(int( test_case_list[x]['num'])) # 如果未循环到该关联的接口 else: LogPrint().info('-----不是被关联的用例----') continue # 如果被关联的接口已执行过,那么就不需要用到这里的for y 的循环了 elif int(test_case_list[x] ['relevance_case']) in check_list: # 如果请求的接口未执行过 if int(test_case_list[x]['num']) not in check_list: LogPrint().info( "----------该用例所关联的接口已执行,继续调用第" + test_case_list[x]['num'] + "个测试用例的接口----------") result_temp = 'execute yet' sql_two = 'select response from test_case where case_id = %d order by create_time desc ' \ 'limit 1' % (int(test_case_list[x]['relevance_case'])) result = md.select_db(conn, cur, sql_two) result_two = result[0][0] # 处理请求接口的数据,将被关联的接口数据赋值给请求的接口数据中 request_data_last = CommonMethod.request_data_deal( test_case_list[x]['request_data'], result_two) ifd = InterfaceDeal( test_case_list[x]['num'], test_case_list[x]['api_purpose'], test_case_list[x]['request_url'], test_case_list[x]['request_method'], test_case_list[x]['request_data_type'], request_data_last, test_case_list[x]['check_point'], test_case_list[x]['test_describe'], test_case_list[x]['relevance_case']) result_temp2, response = ifd.interface_test() check_list.append(int( test_case_list[x]['num'])) LogPrint().info( "----------------根据用例执行情况,开始更新测试结果表的相关数据----------------" ) if result_temp2 == 'success': CommonMethod.sql_deal_two( md, conn, cur, 'success_num', result_id) elif result_temp2 == 'fail': CommonMethod.sql_deal_two( md, conn, cur, 'fail_num', result_id) elif result_temp2 == 'error': CommonMethod.sql_deal_two( md, conn, cur, 'error_num', result_id) else: LogPrint().info('-----该请求接口已执行----') # 未执行的用例,没有关联其他的测试用例,则直接调用interface_test函数,处理该接口即可 else: ''' 这里接口没有关联其他接口,但是可能请求的参数中,会用到已单独封装的接口返回数据,或者其他随机函数的数据,所以需要将接口请求参数 另外再做处理,将未赋值的参数赋值,这里必须要有"data"数据,因为该函数还需要处理其他接口返回的值,这里为方便不修改代码先这样 ''' if test_case_list[x]['request_data_type'] == 'File': request_data_last = CommonMethod.request_type_file( test_case_list[x]['request_data'], test_case_list[x]['num']) else: request_data_last = CommonMethod.request_data_deal( test_case_list[x]['request_data'], '{"code": 0, "msg": "操作成功!", "data": {}}') ifd = InterfaceDeal(test_case_list[x]['num'], test_case_list[x]['api_purpose'], test_case_list[x]['request_url'], test_case_list[x]['request_method'], test_case_list[x]['request_data_type'], request_data_last, test_case_list[x]['check_point'], test_case_list[x]['test_describe'], test_case_list[x]['relevance_case']) result_temp, response = ifd.interface_test() # 该用例已执行过,不需要再次执行 else: LogPrint().info("----------------第" + str(test_case_list[x]['num']) + "个测试用例已执行----------------") continue check_list.append(int(test_case_list[x]['num'])) # LogPrint().info(('-------第' + str(test_case_list[x]['num']) + '个用例的结果是-------:' + result_temp)) LogPrint().info( "----------------根据用例执行情况,开始更新测试结果表的相关数据----------------") if result_temp == 'success': CommonMethod.sql_deal_two(md, conn, cur, 'success_num', result_id) elif result_temp == 'fail': CommonMethod.sql_deal_two(md, conn, cur, 'fail_num', result_id) elif result_temp == 'error': CommonMethod.sql_deal_two(md, conn, cur, 'error_num', result_id) else: LogPrint().info( "----------------被关联的测试用例结果已更新,无需再次更新----------------")