接口关联处理的两大步骤
一、提取变量
1、提取变量的两种方式
(1)正则提取
re.findall(pattern, string, flags=0)
pattern :指定的正则表达式模式。
**string :**要搜索的字符串。
flags :可选参数,用于控制匹配的模式,如忽略大小写、多行模式等。
re.findall()
函数是 Python 中正则表达式库 re
提供的一个强大的函数,用于在字符串中查找所有与正则表达式模式匹配的子。
作用:该函数扫描会整个字符串,返回一个列表,其中包含字符串中所有与正则表达式模式匹配的子串。如果正则表达式中包含组(即用括号括起来的部分),则返回的列表中每个元素是一个元组,元组中的每个元素对应一个组的匹配结果。
(2)jsonpath提取
import jsonpath
# 假设有一个 JSON 数据
data = {
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
# 使用 jsonpath.jsonpath() 提取数据
# 提取所有书籍的作者
authors = jsonpath.jsonpath(data, '$.store.book[*].author')
print(authors) # 输出: ['Nigel Rees', 'Evelyn Waugh']
常见用法
-
提取对象属性:使用点号
.
来访问对象的属性。-
$.store.bicycle.color
提取自行车的颜色。
-
-
提取数组元素:使用
[*]
来提取数组中的所有元素。-
$.store.book[*].title
提取所有书籍的标题。
-
-
条件过滤:使用
?(@.property operator value)
来过滤满足条件的元素。-
$.store.book[?(@.price < 10)]
提取价格小于 10 的书籍。
-
-
通配符:使用
*
作为通配符来匹配任意属性或元素。-
$..book
匹配文档中所有名为book
的元素。
-
2、提取变量的地方
一般在响应的结果中、cookie中、响应头中...........
通过这两个方法提取变量后通过下标取值
3、如何去设计提取方式
在yaml文件中使用这种方式去设计:
extract:
保存变量的值: [取值的地方, 取值的方式, 取值的下标]
-
feature: 常规网站
story: 用户登录接口
title: 用户登录
request:
method: post
url: www.baidu.com
headers:
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
data:
user_name: test01
passwd: admin123
extract:
token: [json,"$.token",0]
4、通过上面这种设计方法我们可以这么做
在common下建立extract_util.py提取工具模块
根据extract:
保存变量名: [取值的地方, 取值的方式, 取值的下标]
第一步:我们设计一个方法,传(响应、变量名、取值名、取值表达式、下标)将最后得到的值放到extract.yaml文件中
class ExtractUtil:
# 提取变量
def extract(self, res, var_name, attr_name, expr, index):
# 深拷贝
new_res = copy.deepcopy(res)
# 把json()方法改成json属性
try:
new_res.json = new_res.json()
except Exception:
new_res.json = {"msg": "response is not json data"}
# 通过反射获取属性的值
data = getattr(new_res, attr_name)
# 判断用什么方式去提取
if expr.startswith("$"):
lis = jsonpath.jsonpath(dict(data), expr)
else:
lis = re.findall(expr, data)
# 通过下标取值
if lis:
write_yaml({var_name: lis[index]})
第二步:因为我们更改了yaml用例,一定得将yaml_model_util.py中类下加入选填的extract
@dataclass
class CaseInfo:
# 必填
feature: str
story: str
title: str
request: dict
validate: dict
# 选填
extract: dict = None
第三步:在发送请求之后得到响应才能去提取变量,通过判断yaml中是否存在extract,有则进行提取操作。
# 请求响应之后去提取接口关联变量
if case_obj.extract:
for key, value in case_obj.extract.items():
eu.extract(res, key, *value)
二、使用变量
在postman中使用变量通常是:{{变量名}}
jmeter中使用变量通常是:${变量名}
根据提取变量的设计使用jmeter这种模式:${变量名}
使用的地方一般在请求四要素中,因此在yaml文件中应该这么去使用
data:
token:${token}
根据上述使用规则(选取替换规则)
第一种:data_str.replace()
第二种:Template模板替换,能替换${变量名}内的值
data = Template("you name is ${name}")
print(data.substitute(name = "OY")) # you name is OY
因此使用第二种替换方法。
在发送请求前去使用替换。编写使用提取的值的方法。
# 在ExtractUtil类下
# 使用变量
def use_extract_value(self, data: dict):
# 把字典转换成字符串
data_str = yaml.safe_dump(data)
# 字符串替换,替换${变量名}的值
new_request_data = Template(data_str).safe.substitute(read_all())
# 把字符串转换成字典
data_dict = yaml.safe_load(new_request_data)
return data_dict
# 在test_all_case.py发送请求前使用替换变量方法
# 使用提取的值,赋值给四要素中为,${变量}
new_request = eu.use_extract_value(new_caseinfo.request)
三、整体代码如下:
common下的extract_util.py
common下 yaml_util.py中读取extract.yaml所有字典的方法
testcase下的test_all_case.py的整体代码