目前为止,responses-validator 的使用方式均是提供一些内容,作为预期内容进行断言。
可以想象的是,在下列情况中我们很难提前准备预期的内容,例如:
基于当前时间的结果
数据库查询的结果
动态计算产生的结果
其他...
这是 yaml 的局限性所决定的。如果需要动态的得到结果,并进行断言,就需要用到 Python 函数。
responses-validator 支持在 yaml 中指定 Python 函数来进行断言,
也支持 Python 调用 responses-validator 中的断言方式,定制化、精细化的断言实现
1. 在响应断言中调用函数
如果整个响应的都通过自定义函数进行断言,只需要添加一个function属性。
function不是 requests 响应的属性,而是 responses-validator 是扩展的,它的内容应该是一个可导入路径。
这和 import 语法、规则非常相似,
只不过最后一个节点不是模块,而是具体的函数,例如:
a.b,等同于from a import
a.b.c,等同于from a.b import c
下面是一个具体的例子:
首先定义一个函数,这个函数必须接受一个参数(响应),并返回一个布尔值(断言结果)
# funcs.py
def check_resp(resp): return True # 返回True则表示通过
接着在 yaml 用例中调用这个函数,
执行结果如下:
图 1. 函数返回 True 使用例测试通过
如果修改函数的返回值为 False,执行结果如下:
图 2. 函数返回 False 使用例测试通过
当然,在实际业务中作为断言的函数应该根据响应来控制返回值
# funcs.py
def check_resp(resp): if resp.status_code != 200: # 检查状态码 return False
if 'baidu' not in resp.text: # 检查响应正文 return False
return True # 返回True则表示通过
2. 在字段断言中调用函数
如果整个响应中,大部分的内容是可以写出预期值的,只有少部分字段需要动态断言,也可以仅在部分字段中使用函数断言。
字段的断言除了 glob、same 等模式外,也支持function模式。
在function模式下,在 value 字段中指定函数的可导入路径
这是一个具体的示例:
# tests/function/test_function_with_header.yamltest_name: 使用自定义函数断言字段steps: - request: method: get url: https://www.baidu.com - response: status_code: 200 headers: connection: value: 'funcs.has_alive' # 使用函数断言响应头的connection字段 mode: 'function' # 指定function模式
函数内容如下
# funcs.py
def has_alive(data):
if 'alive' in data: return True
return False
执行结果如下:
图 3. 为字段使用函数断言
3. 使用 Python 调用断言
为了提高灵活性和扩展性,responses-validator 还支持对 requests 响应之外的数据进行断言。
# tests/function/test_function_other.yamltest_name: 使用自定义函数断言响应steps: - request: method: get url: https://www.baidu.com
- extract: # 自定义数据提取 body: text # 通过响应或其他途径获取数据,保存为code
- validate: # 自定义断言 body: value: '*baidu*' # 对code进行断言 msg: 'body中没有包含baidu'
在上面例子中,没有直接对 request 响应进行断言,
而是对 body 这个单独的数据进行断言。
如果真正的对其进行判断呢?
这需要我们在 Python 代码中调用 responses-validator
# conftest.py
from responses_validator import TextField # 导入文本自动断言类
def pytest_yaml_run_step(item): match key: case 'request': # 步骤1:发送请求,requests的封装使得仅需一行代码 pass
case 'response': # 步骤2:断言响应,本工具封装后也仅需一行代码 pass
case 'extract': # 步骤3:从响应中提取变量 item.var = {} for var_name, attr_name in value.items(): item.var[var_name] = getattr(item.resp, attr_name)
case 'validate': # 步骤4:对变量进行单独断言 for var_name, var_value in value.items(): text_assert = TextField.form_asserts(var_name, var_value) # 实例化断言类 is_pass = text_assert.validate(item.var[var_name]) # 对上一步的数据进行匹配 assert is_pass, text_assert.msg # 断言匹配结果
这样,yaml 用例中的responses_validator风格断言,就可以正常执行了。
这个在 yaml 中,bodu 这个数据可以来自响应,也可以来自数据库,还可以来自变量,或 yaml 文件
不论它来自哪里,都可以使用与响应正文相同的方式进行断言!
至此,本系列已经介绍了如何使用 responses-validator 断言状态码、响应头、响应正文、JSON 正文,
也介绍了如何在 yaml 中调用 python 函数、在 python 函数中使用yaml断言 。
最后,希望你能封装出属于你自己的、更好用的,yaml 接口自动化测试框架!
领取专属 10元无门槛券
私享最新 技术干货