一、在接口调用的时候,参数化遇到复杂json,如果把每个参数当成独立列来对待,数据比较多,维护起来比较复杂
所以我们设计一个方法
1、不需要在数据文件中维护所有参数
2、所有参数默认值在接口定义中维护
3、在数据文件中只维护用例对应的目标参数即可参数格式是{"$.goods_name":""}
4、设计封装一个方法,使用jsonpath来完成数据替换,通过第三步的jsonpath表达式匹配到第二步默认参数目标,并且把新的值替换到默认参数中去,完成测试数据替换。其他参数均采用接口定义中的默认值
二、封装json_util.py
安装第三方库
pip install jsonpath_ng -i Simple Index
json_object是json数据,json_path是要改数据的jsonpath,new_value是要改的数据
json里面参数缺失的情况,传的new_value为$del
import jsonpath
from jsonpath_ng import Index, Fields, parse
from common.logger import GetLogger
def updata_value_to_json(json_object,json_path,new_value):
"""
:param json_object:
:param json_path:
:param new_value: 目标参数对应的测试数据,如果new_value等于$del则代表要删除目标参数
:return:
"""
jsonpath_expr = parse(json_path) # 把传进来的json_path表达式转成jsonpath对象
matches = jsonpath_expr.find(json_object) # 通过jsonpath匹配目标
for match in matches:
path = match.path # 获取当前匹配对象的路径
if isinstance(path, Index): # 判断他是不是一个索引对象路径
if new_value == '$del':
del match.context.value[match.path.index]
else:
match.context.value[match.path.index] = new_value
elif isinstance(path, Fields):
if new_value == '$del':
del match.context.value[match.path.fields[0]]
else:
match.context.value[match.path.fields[0]] = new_value
return json_object
三、准备数据
准备yaml文件数据
接口名称:
- ['casename',{"jsonpath":""},400,'{"code":"","message":""}']
- ['casename',{"$del":""},400,'{"code":"","message":""}']
四、引入测试用例
class Abc:
test_data = real_yaml(mtxshop_data_yaml)['添加收货地址接口']
#test_data:[['casename', {'$.name': ''}, 400, '{"code":"","message":""}']],new_params : {'$.name': ''}
@pytest.mark.parametrize('casename,new_params,expect_status,expect_body', test_data)
def test_add_address_exception(self, casename, new_params, expect_status, expect_body):
api = AddAddressApi()
for json_path, new_value in new_params.items(): #new_params : {'$.name': ''}
api.data = updata_value_to_json(api.data, json_path, new_value)
resp = api.send()
pytest.assume(resp.status_code == expect_status, f'期望值:{expect_status},实际值:{resp.status_code}')
pytest.assume(resp.text == expect_body, f'期望值:{expect_body},实际值:{resp.text}')
五、复杂接口响应数据提取封装
def extract_json(json_object,json_path,index=0):
logger = GetLogger.get_logger()
res = jsonpath.jsonpath(json_object,json_path)
# res如果提取到了值那么他就是一个列表,如果没匹配的值他是Fasle
if res:
logger.info(f'通过{json_path}匹配到的结果是:{res}')
if index<0:
# 如果index小于0,则认为你想要所有的匹配结果
return res
else:
# 如果不小于0,那么你传几,就代表你要的是匹配到某一个
return res[index]
else:
logger.exception(f'通过{json_path}没有提取到值')
if __name__ == '__main__':
TestOrderFlow.order_sn = jsonpath.jsonpath(resp.json(),'$..sn')[0]
TestOrderFlow.order_sn = extract_json(resp.json(),'$..sn')