def __init__(self, file_name, sheet_name=None, sheet_index=0): self.requestUtil = RequestUtil() self.excelUtil = ExcelUtil(file_name, sheet_name, sheet_index) self.dataUtil = DataUtil() self.assetUtil = AssertUtil() self.logger = Logger(self.__class__.__name__).get_logger_with_level() self.cookie_dict = {}
def testIndexCategoryList(self): """ 首页分类列表 """ request = RequestUtil() url = host + "/pub/api/v1/web/all_category" response = request.request(url, "get") self.assertEqual(response['code'], 0, "业务状态不正常") self.assertTrue(len(response["data"]) > 0, "分类列表为空")
def testLogin(self): """ 用户登录 """ request = RequestUtil() url = host + "/pub/api/v1/web/web_login" data = {"phone": "13113777555", "pwd": "1234567890"} headers = {"Content-Type": "application/x-www-form-urlencoded"} response = request.request(url, 'post', param=data, headers=headers) self.assertEqual(response['code'], 0, "登录接口测试失败")
def testIndexVideoCard(self): """ 首页视频卡片 """ request = RequestUtil() url = host + "/pub/api/v1/web/index_card" response = request.request(url, 'get') self.assertEqual(response['code'], 0, "业务状态不正常") self.assertTrue(len(response['data']) > 0, "视频卡片为空") video_card_list = response['data'] for card in video_card_list: self.assertTrue( len(card['title']) > 0, "卡片标题为空 id=" + str(card['id']))
class InterfaceTestCase: def loadAllCaseByApp(self, app): my_db = MysqlDb() sql = "select * from `case` where app='{0}'".format(app) results = my_db.query(sql) return results def findCaseById(self, case_id): my_db = MysqlDb() sql = "select * from `case` where id='{0}'".format(case_id) results = my_db.query(sql, state="one") return results def loadConfigByAppAndKey(self, app, key): my_db = MysqlDb() sql = "select * from `config` where app='{0}' and dict_key='{1}'".format( app, key) results = my_db.query(sql, state="one") return results def updateResultByCaseId(self, response, is_pass, msg, case_id): my_db = MysqlDb() current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') print(current_time) if is_pass: sql = "update `case` set response='{0}', pass='******', msg='{2}', update_time='{3}' where id={4}".format( "", is_pass, msg, current_time, case_id) else: sql = "update `case` set response=\"{0}\", pass='******', msg='{2}', update_time='{3}' where id={4}".format( str(response), is_pass, msg, current_time, case_id) rows = my_db.execute(sql) return rows def runAllCase(self, app): api_host_obj = self.loadConfigByAppAndKey(app, "host") results = self.loadAllCaseByApp(app) for case in results: if case['run'] == 'yes': try: response = self.runCase(case, api_host_obj) assert_msg = self.assertResponse(case, response) rows = self.updateResultByCaseId(response, assert_msg['is_pass'], assert_msg['msg'], case['id']) print("更新结果 rows={0}".format(str(rows))) except Exception as e: print("用例id={0},标题:{1},执行报错:{2}".format( case['id'], case['title'], e)) self.sendTestReport(app) def runCase(self, case, api_host_obj): headers = json.loads(case['headers']) body = json.loads(case['request_body']) method = case['method'] req_url = api_host_obj['dict_value'] + case['url'] if case["pre_case_id"] > -1: pre_case_id = case["pre_case_id"] pre_case = self.findCaseById(pre_case_id) pre_response = self.runCase(pre_case, api_host_obj) pre_assert_msg = self.assertResponse(pre_case, pre_response) if not pre_assert_msg['is_pass']: pre_response['msg'] = "前置条件不通过," + pre_response['msg'] return pre_response pre_fields = json.loads(case['pre_fields']) for pre_field in pre_fields: if pre_field['scope'] == 'header': for header in headers: field_name = pre_field['field'] if header == field_name: field_value = pre_response['data'][field_name] headers[field_name] = field_value elif pre_field['scope'] == 'body': print("替换body") req = RequestUtil() response = req.request(req_url, method, headers=headers, params=body) return response
class SeaclassTestCase: def loadAllCaseByApp(self, app): """ 根据app加载全部测试用例 :param app: :return: """ print("loadAllCaseByApp") my_db = MysqlDb() sql = "select * from `case` where app='{0}'".format(app) results = my_db.query(sql) return results def findCaseById(self, case_id): """ 根据id找测试用例 :param case_id: :return: """ print("findCaseById") my_db = MysqlDb() sql = "select * from `case` where id='{0}'".format(case_id) results = my_db.query(sql, state="one") return results def loadConfigByAppAndKey(self, app, key): """ 根据app和key加载配置 :param app: :param key: :return: """ print("loadConfigByAppAndKey") my_db = MysqlDb() sql = "select * from `config` where app='{0}' and dict_key='{1}'".format(app, key) results = my_db.query(sql, state="one") return results def updateResultByCaseId(self, response, is_pass, msg, case_id): """ 根据测试用例id,更新响应内容和测试内容 :param response: :param is_pass: :param msg: :param case_id: :return: """ print("updateResultByCaseId") my_db = MysqlDb() current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') print(current_time) if is_pass: sql = "update `case` set response='{0}', pass='******', msg='{2}', update_time='{3}' where id={4}".format("", is_pass, msg, current_time, case_id) else: sql = "update `case` set response=\"{0}\", pass='******', msg='{2}', update_time='{3}' where id={4}".format( str(response), is_pass, msg, current_time, case_id) print(sql) rows = my_db.execute(sql) return rows def runAllCase(self, app): """ 执行全部用例的入口 :param app: :return: """ print("runAllCase") # 获取接口域名 api_host_obj = self.loadConfigByAppAndKey(app, "host") # 获取全部用例 results = self.loadAllCaseByApp(app) for case in results: print(case) if case['run'] == 'yes': try: # 执行用例 response = self.runCase(case, api_host_obj) # 断言判断 assert_msg = self.assertResponse(case, response) # 更新结果存储数据库 rows = self.updateResultByCaseId(response, assert_msg['is_pass'], assert_msg['msg'], case['id']) print("更新结果 rows={0}".format(str(rows))) except Exception as e: print("用例id={0},标题:{1},执行报错:{2}".format(case['id'], case['title'], e)) # 发送测试报告 self.sendTestReport(app) def runCase(self, case, api_host_obj): """ 执行单个用例 :param case: :param api_host_obj: :return: """ print("runCase") headers = json.loads(case['headers']) body = json.loads(case['request_body']) method = case['method'] req_url = api_host_obj['dict_value'] + case['url'] # 是否有前置条件 if case["pre_case_id"] > -1: print("是否有前置条件") pre_case_id = case['pre_case_id'] pre_case = self.findCaseById(pre_case_id) # 递归调用 pre_response = self.runCase(pre_case, api_host_obj) # 前置条件断言 pre_assert_msg = self.assertResponse(pre_case, pre_response) if not pre_assert_msg['is_pass']: # 前置条件不通过直接返回 pre_response['msg'] = "前置条件不通过," + pre_response['msg'] return pre_response # 判断需要case的前置条件是哪个字段 pre_fields = json.loads(case['pre_fields']) for pre_field in pre_fields: print(pre_field) if pre_field['scope'] == 'header': # 遍历headers ,替换对应的字段值,即寻找同名的字段 for header in headers: field_name = pre_field['field'] if header == field_name: field_value = pre_response['data'][field_name] headers[field_name] = field_value elif pre_field['scope'] == 'body': print("替换body") print(headers) # 发起请求 req = RequestUtil() response = req.request(req_url, method, headers=headers, param=body) return response
class RunCase(object): CASE_ID = 1 MODULE_NAME = 2 CASE_NAME = 3 RUN_FLAG = 4 URL = 5 REQUEST_METHOD = 6 HEADERS = 7 COOKIES = 8 REQUEST_PARAM = 9 EXP_RESULT = 10 STATUS_CODE = 11 RESPONSE_TEXT = 12 ASSET_TYPE = 13 ASSET_PATTERN = 14 EXEC_RESLT = 15 """定义常量,指定表格每一列""" def __init__(self, file_name, sheet_name=None, sheet_index=0): self.requestUtil = RequestUtil() self.excelUtil = ExcelUtil(file_name, sheet_name, sheet_index) self.dataUtil = DataUtil() self.assetUtil = AssertUtil() self.logger = Logger(self.__class__.__name__).get_logger_with_level() self.cookie_dict = {} def run_case_by_data(self, data): """根据数据执行单个用例,格式:{"1":[test_001,订单,下单,www.baidu.com,xx,xx,]}""" row_no = 2 for key in data: row_no = key break row_data = data.get(row_no) self.logger.info( "执行用例:%s-%s-%s" % (row_data[RunCase.CASE_ID - 1], row_data[RunCase.MODULE_NAME - 1], row_data[RunCase.CASE_NAME - 1])) # 数据准备 case_id = row_data[self.CASE_ID - 1] # module_name = row_data[self.MODULE_NAME-1] run_flag = row_data[self.RUN_FLAG - 1] if run_flag == '否': # 用例不执行 return elif run_flag == '是': url = row_data[self.URL - 1] request_method = row_data[self.REQUEST_METHOD - 1] # 请求头处理 headers = row_data[self.HEADERS - 1] if headers is None: headers = {} else: headers = self.dataUtil.str_to_json(headers) # cookie处理 cookies = row_data[self.COOKIES - 1] if cookies: # 进行cookie的解析处理,判断是否存在cookie依赖 depend_cookie = self.cookie_depend(cookies) if depend_cookie is not None: if type(depend_cookie) == RequestsCookieJar: cookies = depend_cookie elif depend_cookie == '': cookies = {} else: cookies = self.dataUtil.str_to_json(depend_cookie) request_param = row_data[self.REQUEST_PARAM - 1] if request_param is not None: request_param = self.data_depend(request_param) exp_result = row_data[self.EXP_RESULT - 1] asset_type = row_data[self.ASSET_TYPE - 1] asset_pattern = row_data[self.ASSET_PATTERN - 1] # 执行并记录结果 self.logger.info("请求URL:%s" % url) self.logger.info("请求参数:%s" % request_param) self.logger.info("请求头:%s" % headers) self.logger.info("请求cookie:%s" % cookies) response = None if request_method == 'get': response = self.requestUtil.do_get(url, request_param, headers, cookies) elif request_method == 'post': # 将字符串转换成json对象 json_param = self.dataUtil.str_to_json(request_param) response = self.requestUtil.do_post(url, json_param, '', headers, cookies) response_text = response.text.strip() if case_id in self.cookie_dict: self.cookie_dict[case_id] = response.cookies self.logger.info("请求结果:%s\n" % response_text) self.excelUtil.set_data_by_row_col_no(row_no, self.STATUS_CODE, response.status_code) self.excelUtil.set_data_by_row_col_no(row_no, self.RESPONSE_TEXT, response_text) # 断言判断,记录最终结果 result = self.asset_handle(exp_result, response_text, asset_type, asset_pattern) if result: self.excelUtil.set_data_by_row_col_no(row_no, self.EXEC_RESLT, 'pass') else: self.excelUtil.set_data_by_row_col_no(row_no, self.EXEC_RESLT, 'fail') return result def data_depend(self, request_param): """处理数据依赖 ${test_03.data.orderId} 表示对返回结果的部分属性存在依赖 """ request_param_final = None # 处理返回结果属性依赖 match_results = re.findall(r'\$\{.+?\..+?\}', request_param) if match_results is None or match_results == []: return request_param else: for var_pattern in match_results: # 只考虑匹配到一个的情况 start_index = var_pattern.index("{") end_index = var_pattern.rindex("}") # 得到${}$中的值 pattern = var_pattern[start_index + 1:end_index] spilit_index = pattern.index(".") # 得到依赖的case_id和属性字段 case_id = pattern[:spilit_index] proper_pattern = pattern[spilit_index + 1:] row_no = self.excelUtil.get_row_no_by_cell_value( case_id, self.CASE_ID) response = self.excelUtil.get_data_by_row_col_no( row_no, self.RESPONSE_TEXT) result = self.dataUtil.json_data_analysis( proper_pattern, response) # 参数替换,str(result)进行字符串强转,防止找到的为整数 request_param_final = request_param.replace( var_pattern, str(result), 1) return request_param_final def cookie_depend(self, request_param): """处理数据依赖 1、${test_01} 表示对返回cookie存在依赖 2、${test_03.data.orderId} 表示对返回结果的部分属性存在依赖 """ cookie_final = None # 处理对返回cookie的依赖 match_results = re.match(r'^\$\{(.[^\.]+)\}$', request_param) if match_results: # 用例返回cookie依赖 depend_cookie = self.cookie_dict[match_results.group(1)] return depend_cookie else: # 非用例返回cookie依赖 cookie_final = self.data_depend(request_param) return cookie_final def asset_handle(self, exp_result, response_text, asset_type, asset_pattern): """根据断言方式进行断言判断""" asset_flag = None if asset_type == '相等': if asset_pattern is None or asset_pattern == '': asset_flag = self.assetUtil.equals(exp_result, response_text) else: exp_value = self.dataUtil.json_data_analysis( asset_pattern, exp_result) response_value = self.dataUtil.json_data_analysis( asset_pattern, response_text) asset_flag = self.assetUtil.equals(exp_value, response_value) elif asset_type == '包含': asset_flag = self.assetUtil.contains(response_text, asset_pattern) elif asset_type == '正则': asset_flag = self.assetUtil.re_matches(response_text, asset_pattern) return asset_flag