本文首发于:行者AI
在接口自动化测试过程中不仅仅有单接口的测试,场景测试也必不可少,这就造成接口与接口之间存在传值问题,上面介绍一下在 pytest 框架下怎么进行接口传值解决。
接口数据总体可分为前置解决和后置解决:
前置解决:一些固定值或固定办法的调用
后置解决:须要前几个申请中的body(参数)、response(响应)
1. 数据筹备
前置解决:
前置解决用<>和[]来标记(标记符可按本人需要进行更改),正则匹配数据中蕴含这两种标记时,读取调用methlib.py或config.py中的办法,具体调用哪个固定值或办法,依据标记外面写入的参数调用,并对数据进行替换。其中<>用于标记固定值,[]用于标记固定办法;
后置解决:
后置解决用&&、{}、==、##来标记(标记符可按本人需要进行更改),正则匹配数据中蕴含这几种标记时,读取requestmsg.txt中数据,具体读取哪一行数据,依据关联列的数据进行判断,并对数据进行替换。其中&&用于标记取上一步的body、{}用于标记取上一步的response、==用于标记取前几步的body、##用于标记前上几步的response;
注:
① excel表中的用例传参数据须要以字典模式写入。
② 表格数据中退出关联列,用于判断读取第几个申请的参数或响应。
③ 对于局部接口须要加密的接口,在表格数据中退出是否加密列,用于判断该接口的参数是否加密。
2. 测试流程
前置解决:
读取到的excel表格数据是一个模块的数据,通过pytest的解决,会将模块中的多个接口数据(列表)进行单个接口的传输,是不必通过任何申请失去的数据,所以将其放在独自的数据处理中。上面是仅通过前置解决的流程;
后置解决:
须要通过后面几个接口的申请或响应而失去的数据,所以必须将其放在request申请之前,并且每发送一个接口申请,都须要在request.txt中写入该申请的body和response,以便给前面的接口应用。上面是仅通过后置解决的流程;
上面是通过前置和后置解决的接口测试流程;
3. 代码实现
前置解决的实现:前置解决与其余申请的参数、响应无关,所以能够整个模块进行解决。
def param_method(dic_param): """ 固定值、取办法(不须要上一步的body和response) :param dic_param: 必须是个字典(data外面的参数) :return: """ temp_mobile_ = [] temp_email_ = [] temp_pid_ = [] for j in dic_param.keys(): value__ = dic_param[j] _ = re.findall(r'\<(.*?)>', str(value__)) # 固定值 __ = re.findall(r'\[(.*?)]', str(value__)) # 取办法 if _: # 判断是否存在apk固定传值 dic_param[j] = param[f'{_[0]}'] if __: if j == 'mobile' or 'phone' or 'phoneNum': dic_param[j] = mobile() temp_mobile_.append(dic_param[j]) if j == 'email': dic_param[j] = email() temp_email_.append(dic_param[j]) if j == 'pid': dic_param[j] = pid() temp_pid_.append(dic_param[j]) if j == 'app_order_id': dic_param[j] = get_random_str(30) return dic_param
后置解决的实现:后置解决与其余申请的参数、响应相干,所以必须在每个申请之前进行解决,上面展现的是后置解决的办法,因为代码过长,只展现了局部后置解决代码。
def prev_body_res(dic_param, relevance=None): ''' 取上步body、取上步response,当relevance不为空时取上几步body、response :param dic_param: 必须是字典格局 :return: ''' request_file = r'./requestsmsg.txt' for j in dic_param.keys(): value__ = dic_param[j] ___ = re.findall(r'\&(.*?)&', str(value__)) # 取上步body ____ = re.findall(r'\{(.*?)}', str(value__)) # 取上步response _____ = re.findall(r'\#(.*?)#', str(value__)) # 取前几步的response ______ = re.findall(r'\=(.*?)=', str(value__)) # 取前几步的body if ___: request_res = readtxt(request_file) request_body = request_res[1] key = ___[0] res_data = request_body[f'{key}'] dic_param[j] = str(res_data) if ____: request_response = readtxt(request_file) request_response = request_response[0] key = ____[0] res_data = request_response['data'] if res_data: if isinstance(res_data, list): temp_value = get_dict_value(request_response['data'][0], key) dic_param[j] = temp_value[0] temp_value.clear() else: temp_value = request_response['data'][f'{key}'] dic_param[j] = str(temp_value)
后置解决具体利用:因为后置解决须要后面的申请实现之后能力失去想要的数据,所以具体后置解决放在每个申请解决之前,上面展现的是具体申请的利用。
else: # 传值 line_data = prev_body_res(line_data, relevance_no) if i['encryption'] == '0': # 不加密 if header['Content-Type'] == 'application/json': response = requests.request(f'{request_type}', url=url, headers=header, data=json.dumps(line_data)) write_request(response.json(), no, line_data) logger.info(f'response:{response.json()},no:{no},body:{line_data}')
基于pytest实现的模块传值解决:以数据筹备中的邮箱登录模块为例:parametrize这个装璜器能够将整个模块的数据进行逐个发送给上面定义的办法。
@allure.story('邮箱登录') @pytest.mark.qa @pytest.mark.formal @pytest.mark.parametrize('excel_data', change_data(module_data('邮箱登录'), len(module_data('邮箱登录')))) def test_login_email(self, excel_data): response = decide_value_relevance(excel_data) judge_result(response, '邮箱登录') title = excel_data['title'] allure.dynamic.title(f'邮箱登录:{title}')
4. 总结
基于pytest咱们能够将咱们须要测试的场景以模块模式组装起来,再利用传值,就可构建出多个不同的失常、异样场景,减少关联性;利用表格来构建数据,也减少了构建脚本的灵活性;前期还有许多优化的中央,心愿和大家一起来探讨。