API测试示例¶
备注
本文API测试 特指HTTP API 测试
场景分析¶
HTTP是一个无状态协议,其通讯过程可简要描述为:发送请求、回复响应,所以,API测试步有不同的类型需要处理:
构造请求
断言响应
备注
在复杂的项目场景下,可能包含更多的步骤类型,例如接口mock、变量提取、延迟请求等
其中请求在前响应在后,这就需要钩子在处理步骤时注意顺序。
此外,一个用例中可能需要多次调用不同的接口,而后仅进行一次断言,这就需要钩子在处理步骤时放松约束。
安装依赖¶
pytest自身无法发送HTTP请求,也无法断言响应,需要安装第三方依赖
pip install requests responses-validator
其中:
requests :用来发送HTTP请求
responses-validator :用来断言HTTP响应
如果还需要其他步骤类型,安装对应的依赖即可。
设计用例¶
根据分析结论和依赖的具体用法,设计yaml版API测试用例如下:
name: 访问百度首页
steps:
- request: # 步骤 1:发送请求
method: get
url: https://www.baidu.com
- response: # 步骤 2:断言响应(成功)
status_code: 200
text: "*baidu*"
- response: # 步骤 3:另一个断言(失败)
status_code: 404
在这个用例中,进行了一次HTTP请求,并对结果进行2次断言, 其中一次断言成功,第二次断言失败,使用例整体的结果为:测试失败。
实现钩子¶
# conftest.py
from requests import request
from responses_validator import validator
from pytest_yaml import YamlItem
def pytest_yaml_run_step(item: YamlItem):
step = item.current_step # 从参数值中取出字典格式的测试步骤
step_type = list(step.keys())[0] # 从字典的key即为类型
step_data = list(step.values())[0] # 从字典的value即为步骤内容
match step_type: # 根据不同的步骤类型,匹配不同的测试动作
case 'request':
# 发送请求,并将响应保存到item中,以便后续hook进行处理
item.resp = request(**step_data)
print(f'请求成功!{step_data["method"]} {step_data["url"]}')
case 'response':
validator(item.resp, **step_data)
print('断言成功!')
return True
执行结果如下:
(.venv) C:\demo\pytest-yaml-demo>pytest
=========================== test session starts ============================
platform win32 -- Python 3.12.0, pytest-8.3.4, pluggy-1.5.0
rootdir: C:\demo\pytest-yaml-demo
configfile: pytest.ini
plugins: yaml-1.1.0
collected 1 item
test_api.yaml F [100%]
================================= FAILURES =================================
__________________________________ 访问百度首页 __________________________________
:
Step no: 2
Step Content:
--------------------
response:
status_code: 404
--------------------
src\\responses_validator\\__init__.py:49: ResponseAssertionError
{'status_code': "status_code is 200 and does not match the pattern '404'."}
--------------------------- Captured stdout call ---------------------------
测试步骤:0, 步骤类型: request, 步骤内容: {'method': 'get', 'url': 'https://www.baidu.com'} ...请求成功!
测试步骤:1, 步骤类型: response, 步骤内容: {'status_code': 200, 'text': '*baidu*'} ...断言成功!
测试步骤:2, 步骤类型: response, 步骤内容: {'status_code': 404} ...
========================= short test summary info ==========================
FAILED test_api.yaml::访问百度首页
============================ 1 failed in 0.15s =============================
从结果来看,请求接口和第一次断言都成功了,第二次断言失败了。
具体原因是: status_code is 200 and does not match the pattern '404'
(状态码是200,和预期结果404不匹配)
小结¶
和此前的数学运算相比,接口测试更加添加真实的业务需求。 在真实的业务需求中,往往需要对口的第三方库进行配合,还熟悉业务特征,了解业务步骤。 这些最终都会反应在yaml用例文件和hook钩子函数中。
pytest-yaml-sanmu 并不会代替你理解业务特征,也不会贸然提供一个解决方案。而是帮助你将自己的想法和理解进行落地。