在测试过程中经常会涉及到接口关联的,比如需要上一个接口返回的参数作为下一个接口的入参,这里就涉及到热加载,即让yaml文件可以调用外部函数。
一、提取上一个接口返回的参数保存到extract.yaml文件中
这里支持两种提取方式:正则表达式和jsonpath表达式提取
# 提取值并写入extract.yaml文件
if "extract" in caseinfo.keys():
for key, value in caseinfo["extract"].items():
if "(.*?)" in value or "(.+?)" in value: # 正则表达式
zz_value = re.search(value, return_text)
if zz_value:
extract_value = {key: zz_value.group(1)}
write_yaml(os.path.dirname(os.getcwd()) + '/run/extract.yaml', extract_value)
else: # jsonpath
js_value = jsonpath.jsonpath(return_json, value)
if js_value:
extract_value = {key: js_value[0]}
write_yaml(os.path.dirname(os.getcwd()) + '/run/extract.yaml', extract_value)
以jsonpath为例,接口响应是json串,提取jwt的值保存为token。
-
name: $ddt{name}
parameterize:
name-userName-password-assert_str: /testdatas/get_user_data.yaml
request:
url: *******
method: POST
data:
userName: $ddt{userName}
password: $ddt{password}
extract:
token: $.jwt
validate:
- equals: {status_code: 200}
- contains: $ddt{assert_str}
注意,这边是dict,不是list,token前面是没有-的。
二、在yaml用例中调用token
首先,创建hotloads文件夹,在文件夹下创建test.py文件,定义从extract.yaml文件中取值的方法。
#!/usr/bin/python3
# -*- coding:utf-8 -*-
# @Time : 2023/7/1 21:21
# @Author : 凌雪
# @File : test.py
# @Software: PyCharm
# 功能说明:热加载方法,在yaml用例中调用
from common.yaml_util import *
class Test:
def read_extract_data(self,key):
"""
从extract.yaml文件中读取动态参数值
:param key: 动态参数名称
:return: 动态参数值
"""
return read_yaml(key)
然后,定义替换值的方法
def replace_value(self, data):
"""
替换值的方法
:param data:
:return:
"""
if data:
data_type = type(data) # 保存数据类型
# 判断数据类型转换成str
if isinstance(data, dict) or isinstance(data, list):
str_data = json.dumps(data)
print("str_data:" + str_data)
else:
str_data = str(data)
for cs in range(1, str_data.count('${') + 1):
# 替换
if "${" in str_data and "}" in str_data:
start_index = str_data.index("${")
end_index = str_data.index("}", start_index)
old_value = str_data[start_index:end_index + 1]
# print("old_value:" + old_value)
# 反射:通过类的对象和方法字符串调用方法
func_name = old_value[2:old_value.index('(')]
# print("func_name:" + func_name)
args_value1 = old_value[old_value.index("(") + 1:old_value.index(")")]
new_value = ""
# new_value = read_yaml(old_value[2:-1])
# str_data = str_data.replace(old_value, new_value)
if args_value1 !="":
args_value2 = args_value1.split(',')
new_value = getattr(self.obj, func_name)(*args_value2)
else:
new_value = getattr(self.obj, func_name)()
str_data = str_data.replace(old_value, str(new_value))
# 还原数据类型
if isinstance(data, dict) or isinstance(data, list):
data = json.loads(str_data)
else:
data = data_type(str_data)
return data
在测试用例中调用要加载的方法类
#!/usr/bin/python3
# -*- coding:utf-8 -*-
# @Time : 2023/7/1 16:43
# @Author : 凌雪
# @File : test_swiper.py
# @Software: PyCharm
# 功能说明:******管理测试
import pytest
from common.send_request import Send_Request
from common.parameterize_util import ddt, read_testcase
import allure
from hotloads.test import Test
@allure.feature("****测试")
class TestHomepage:
@allure.story("*****的接口")
@pytest.mark.parametrize('testdata', read_testcase('swiper\\swiper.yaml'))
def test_getheadinfo(self, testdata):
res = Send_Request("trainurl", Test()).standard_yaml(testdata)
这边需要用到的是Test类中从extract.yaml文件中读取动态参数的方法,所以这里传的obj是Test()。
最后,在yaml用例中调用函数。
-
name: ****列表
request:
url: ******
method: GET
headers:
token: ${read_extract_data(token)}
params:
page: 1
size: 20
query:
datatype: 3
extract:
lunboid: $.info.list[0].id
validate:
- equals: {statue: 200}
- equals: {msg: 查询成功}