Pytest 的 Responses Validator 详解
1. 什么是 Responses Validator
1.1 Responses Validator 简介
responses-validator 是一个专门用于验证 HTTP 响应的 Python 库,它提供了声明式的方式来定义复杂的响应验证规则。这个库的设计理念是”验证即数据”(validation as data),将验证规则从测试代码中分离出来,使用 YAML 格式来定义验证规则。
1.2 Responses Validator 的特点
- 🚀 易于使用:支持 YAML 配置和 Python 代码两种方式
- 🎯 多种验证模式:支持精确匹配、通配符、正则表达式、JSON Path 等
- 📝 详细的错误信息:验证失败时提供清晰的错误原因
- 🔧 高度可定制:支持自定义验证函数
- 📋 类型提示:完整支持类型注解
- 🌟 灵活的验证规则:每个字段都支持简单和详细两种配置方式
1.3 Responses Validator 的核心优势
1.3.1 关注点分离
在传统的测试中,断言逻辑往往与代码紧密耦合,难以维护。responses-validator 将验证规则抽象到独立的 YAML 文件中,实现了”验证即数据”的模式。这样做的好处包括:
- 测试工程师或 QA 人员可以专注于编写和维护 YAML 验证文件,无需深入了解测试框架的内部实现
- 代码与数据分离:测试代码和验证规则分离,便于维护和修改
- 可读性和可维护性:YAML 格式的验证规则比 Python 代码更容易阅读和管理,特别是当有很多断言时
- 可重用性:同一套验证规则可以轻松地在不同的测试用例中重用,甚至在不同的项目中重用
1.3.2 在测试中的作用
在 pytest 测试中,responses-validator 主要用于:
- API 接口测试:验证 RESTful API 的各种接口响应
- 响应数据验证:验证 API 返回的数据格式和内容
- 自动化测试:在自动化测试流程中验证 HTTP 响应
- 接口监控:监控接口的响应是否符合预期
- 数据驱动测试:结合 YAML 文件实现数据驱动的测试
1.4 系统要求
- Python 版本:Python >= 3.12
- 依赖库:requests(或 httpx)
2. 安装 Responses Validator
2.1 使用 pip 安装
# 使用 pip 安装最新版本
pip install responses-validator
# 使用 pip 安装指定版本
pip install responses-validator==0.3.0
# 使用 pip 从国内镜像源安装(推荐)
pip install responses-validator -i https://pypi.tuna.tsinghua.edu.cn/simple
2.2 验证安装是否成功
安装完成后,可以通过以下方式验证:
# 方式一:检查版本
import responses_validator
print(responses_validator.__version__) # 输出:0.3.0
# 方式二:尝试导入
from responses_validator import validator
print("安装成功!")
2.3 安装依赖库
responses-validator 主要与 requests 库配合使用,如果你还没有安装 requests,需要先安装:
pip install requests
如果你使用的是 httpx,也可以配合使用:
pip install httpx
3. 基础使用
3.1 YAML 模式(推荐)
YAML 模式是最推荐的使用方式,它将验证规则与测试代码完全分离。
3.1.1 基本示例
步骤一:创建 YAML 验证文件
创建一个名为 validation.yaml 的文件:
# validation.yaml
status_code: 200
headers:
content-type: 'application/json'
json:
id: 1
name: "*"
text: "*success*"
步骤二:在测试中使用
import pytest
import requests
from responses_validator import validator
from yaml import safe_load
def test_api_with_yaml():
"""使用 YAML 文件进行响应验证"""
# 加载 YAML 验证配置
with open('validation.yaml', 'r', encoding='utf-8') as f:
validate_config = safe_load(f)
# 发送请求
response = requests.get("https://api.example.com/users/1")
# 使用 validator 进行验证(验证失败会抛出异常)
validator(response, **validate_config)
print("✅ 验证通过!")
3.1.2 详细说明
在上面的示例中:
status_code: 200:验证响应状态码必须是 200headers: content-type: 'application/json':验证响应头中的content-type必须包含application/jsonjson: id: 1:验证 JSON 响应中必须包含id字段,且值为 1- *`json: name: ““
**:验证 JSON 响应中必须包含name字段,值可以是任意内容(*` 是通配符) text: "*success*":验证响应文本中必须包含success字符串
3.2 Python 模式
Python 模式允许直接在代码中传递验证参数,适合简单的验证场景。
3.2.1 基本示例
import pytest
import requests
from responses_validator import validator
def test_api_with_python():
"""使用 Python 参数进行响应验证"""
# 发送请求
response = requests.get("https://api.example.com/users/1")
# 方式一:验证失败时抛出异常(默认行为)
validator(
response,
status_code=200,
headers={"content-type": "application/json*"},
json={"id": 1, "name": "*"},
text="*success*"
)
print("✅ 验证通过!")
3.2.2 不抛出异常的模式
如果你希望验证失败时不抛出异常,而是返回错误信息,可以设置 raise_exception=False:
import pytest
import requests
from responses_validator import validator
def test_api_without_exception():
"""验证失败时不抛出异常,返回错误信息"""
# 发送请求
response = requests.get("https://api.example.com/users/1")
# 方式二:验证失败时不抛出异常,返回错误字典
errors = validator(
response,
status_code=200,
headers={"content-type": "application/json*"},
json={"id": 1, "name": "*"},
text="*success*",
raise_exception=False # 不抛出异常
)
if errors:
print("❌ 验证失败:")
for field, message in errors.items():
print(f" {field}: {message}")
else:
print("✅ 验证通过!")
3.3 两种模式的对比
| 特性 | YAML 模式 | Python 模式 |
|---|---|---|
| 可读性 | ⭐⭐⭐⭐⭐ 非常好 | ⭐⭐⭐ 一般 |
| 可维护性 | ⭐⭐⭐⭐⭐ 非常好 | ⭐⭐⭐ 一般 |
| 灵活性 | ⭐⭐⭐⭐ 很好 | ⭐⭐⭐⭐⭐ 非常好 |
| 适用场景 | 复杂验证规则、数据驱动测试 | 简单验证、快速测试 |
| 代码分离 | ✅ 完全分离 | ❌ 耦合在代码中 |
建议:
- 对于复杂的验证规则,推荐使用 YAML 模式
- 对于简单的验证,可以使用 Python 模式
4. 状态码验证(status_code)
状态码验证是最基础的验证类型,用于验证 HTTP 响应的状态码是否符合预期。
4.1 单个状态码验证
验证响应状态码必须等于指定的值:
# 验证状态码必须是 200
status_code: 200
Python 代码示例:
import requests
from responses_validator import validator
def test_status_code_single():
"""验证单个状态码"""
response = requests.get("https://api.example.com/users")
# 验证状态码必须是 200
validator(response, status_code=200)
print("✅ 状态码验证通过!")
4.2 通配符匹配
使用通配符 * 可以匹配一类状态码:
# 匹配所有 2xx 状态码(200, 201, 202, 204 等)
status_code: "2*"
注意:使用通配符时,必须用引号将值括起来。
Python 代码示例:
import requests
from responses_validator import validator
def test_status_code_wildcard():
"""使用通配符验证状态码"""
response = requests.post("https://api.example.com/users", json={"name": "test"})
# 验证状态码必须是 2xx(200, 201, 202, 204 等)
validator(response, status_code="2*")
print("✅ 状态码验证通过!")
4.3 多个可能的状态码
使用 | 分隔符可以指定多个可能的状态码:
# 状态码可以是 200、201 或 204 中的任意一个
status_code: "200|201|204"
Python 代码示例:
import requests
from responses_validator import validator
def test_status_code_multiple():
"""验证多个可能的状态码"""
response = requests.post("https://api.example.com/users", json={"name": "test"})
# 状态码可以是 200、201 或 204
validator(response, status_code="200|201|204")
print("✅ 状态码验证通过!")
4.4 复杂匹配
可以组合使用通配符和多个值:
# 匹配 2xx 或 3xx 状态码
status_code: "20*|30*"
Python 代码示例:
import requests
from responses_validator import validator
def test_status_code_complex():
"""复杂的状态码匹配"""
response = requests.get("https://api.example.com/users")
# 匹配 2xx 或 3xx 状态码
validator(response, status_code="20*|30*")
print("✅ 状态码验证通过!")
4.5 实际应用示例
import pytest
import requests
from responses_validator import validator
class TestUserAPI:
"""用户 API 测试类"""
def test_get_user_success(self):
"""测试获取用户成功"""
response = requests.get("https://api.example.com/users/1")
validator(response, status_code=200)
def test_create_user_success(self):
"""测试创建用户成功"""
data = {"name": "张三", "email": "zhangsan@example.com"}
response = requests.post("https://api.example.com/users", json=data)
# 创建成功可能是 201
validator(response, status_code="200|201")
def test_delete_user_success(self):
"""测试删除用户成功"""
response = requests.delete("https://api.example.com/users/1")
# 删除成功可能是 200 或 204
validator(response, status_code="200|204")
def test_user_not_found(self):
"""测试用户不存在"""
response = requests.get("https://api.example.com/users/99999")
# 用户不存在应该返回 404
validator(response, status_code=404)
5. 文本验证(text)
文本验证用于验证 HTTP 响应的文本内容是否符合预期。支持多种验证模式。
5.1 简单字符串匹配(glob 模式)
默认使用 glob 模式(通配符匹配),支持 * 和 ? 通配符:
# 验证响应文本中包含 "success"
text: "*success*"
Python 代码示例:
import requests
from responses_validator import validator
def test_text_glob():
"""使用 glob 模式验证文本"""
response = requests.get("https://api.example.com/status")
# 验证响应文本中包含 "success"
validator(response, text="*success*")
print("✅ 文本验证通过!")
5.2 数字自动转换
如果提供的是数字,会自动转换为字符串:
# 数字会自动转换为字符串
text: 12345
Python 代码示例:
import requests
from responses_validator import validator
def test_text_number():
"""数字自动转换为字符串"""
response = requests.get("https://api.example.com/count")
# 数字会自动转换为字符串进行匹配
validator(response, text=12345)
print("✅ 文本验证通过!")
5.3 详细配置模式
对于更复杂的验证需求,可以使用详细配置:
5.3.1 精确匹配(same 模式)
text:
value: "Welcome home"
mode: same # 精确匹配
msg: "响应内容必须完全等于 'Welcome home'"
Python 代码示例:
import requests
from responses_validator import validator
def test_text_exact():
"""精确匹配文本"""
response = requests.get("https://api.example.com/welcome")
# 精确匹配
validator(
response,
text={
"value": "Welcome home",
"mode": "same",
"msg": "响应内容必须完全等于 'Welcome home'"
}
)
print("✅ 文本验证通过!")
5.3.2 正则表达式匹配(re 模式)
text:
value: "^Welcome(?:to)?[a-zA-Z]+$"
mode: re # 正则表达式匹配
msg: "响应内容必须以 'Welcome' 或 'Welcome to' 开头"
Python 代码示例:
import requests
from responses_validator import validator
import re
def test_text_regex():
"""使用正则表达式验证文本"""
response = requests.get("https://api.example.com/welcome")
# 正则表达式匹配
validator(
response,
text={
"value": "^Welcome(?:to)?[a-zA-Z]+$",
"mode": "re",
"msg": "响应内容格式不正确"
}
)
print("✅ 文本验证通过!")
5.3.3 自定义函数验证(function 模式)
text:
value: "lambda text: len(text) > 100"
mode: function # 自定义函数验证
msg: "响应文本长度必须大于 100 个字符"
Python 代码示例:
import requests
from responses_validator import validator
def test_text_function():
"""使用自定义函数验证文本"""
response = requests.get("https://api.example.com/article")
# 自定义函数验证
validator(
response,
text={
"value": "lambda text: len(text) > 100",
"mode": "function",
"msg": "响应文本长度必须大于 100 个字符"
}
)
print("✅ 文本验证通过!")
5.4 实际应用示例
import pytest
import requests
from responses_validator import validator
class TestTextValidation:
"""文本验证测试类"""
def test_api_success_message(self):
"""验证 API 成功消息"""
response = requests.post("https://api.example.com/users", json={"name": "test"})
validator(response, text="*success*")
def test_error_message_format(self):
"""验证错误消息格式"""
response = requests.post("https://api.example.com/users", json={})
validator(
response,
text={
"value": ".*error.*",
"mode": "re",
"msg": "错误消息格式不正确"
}
)
def test_response_length(self):
"""验证响应长度"""
response = requests.get("https://api.example.com/data")
validator(
response,
text={
"value": "lambda text: len(text) > 500",
"mode": "function",
"msg": "响应内容太短"
}
)
6. 响应头验证(headers)
响应头验证用于验证 HTTP 响应头是否符合预期。每个响应头字段都支持文本验证的所有模式。
6.1 简单键值匹配
最简单的验证方式,直接指定响应头名称和期望值:
headers:
content-type: "application/json"
server: "nginx*"
Python 代码示例:
import requests
from responses_validator import validator
def test_headers_simple():
"""简单响应头验证"""
response = requests.get("https://api.example.com/users")
# 验证响应头
validator(
response,
headers={
"content-type": "application/json",
"server": "nginx*"
}
)
print("✅ 响应头验证通过!")
6.2 详细配置模式
对于需要更精确控制的响应头,可以使用详细配置:
6.2.1 精确匹配
headers:
content-type:
value: "application/json"
mode: same # 精确匹配
msg: "响应类型必须是 JSON"
Python 代码示例:
import requests
from responses_validator import validator
def test_headers_exact():
"""精确匹配响应头"""
response = requests.get("https://api.example.com/users")
validator(
response,
headers={
"content-type": {
"value": "application/json",
"mode": "same",
"msg": "响应类型必须是 JSON"
}
}
)
print("✅ 响应头验证通过!")
6.2.2 正则表达式匹配
headers:
server:
value: "nginx.*"
mode: re # 正则表达式匹配
msg: "服务器必须是 nginx"
Python 代码示例:
import requests
from responses_validator import validator
def test_headers_regex():
"""使用正则表达式验证响应头"""
response = requests.get("https://api.example.com/users")
validator(
response,
headers={
"server": {
"value": "nginx.*",
"mode": "re",
"msg": "服务器必须是 nginx"
}
}
)
print("✅ 响应头验证通过!")
6.2.3 自定义函数验证
headers:
x-rate-limit-remaining:
value: "lambda x: int(x) > 0"
mode: function # 自定义函数验证
msg: "API 调用次数限制已用完"
Python 代码示例:
import requests
from responses_validator import validator
def test_headers_function():
"""使用自定义函数验证响应头"""
response = requests.get("https://api.example.com/users")
validator(
response,
headers={
"x-rate-limit-remaining": {
"value": "lambda x: int(x) > 0",
"mode": "function",
"msg": "API 调用次数限制已用完"
}
}
)
print("✅ 响应头验证通过!")
6.3 混合使用
可以在同一个验证配置中混合使用简单和详细配置:
headers:
content-type: "application/json" # 简单配置
server: # 详细配置
value: "nginx*"
mode: glob
msg: "服务器必须是 nginx"
Python 代码示例:
import requests
from responses_validator import validator
def test_headers_mixed():
"""混合使用简单和详细配置"""
response = requests.get("https://api.example.com/users")
validator(
response,
headers={
"content-type": "application/json", # 简单配置
"server": { # 详细配置
"value": "nginx*",
"mode": "glob",
"msg": "服务器必须是 nginx"
}
}
)
print("✅ 响应头验证通过!")
6.4 响应头大小写不敏感
重要提示:响应头的键名会自动转换为小写进行匹配,所以 Content-Type 和 content-type 是等价的。
import requests
from responses_validator import validator
def test_headers_case_insensitive():
"""响应头键名大小写不敏感"""
response = requests.get("https://api.example.com/users")
# 以下两种写法是等价的
validator(response, headers={"Content-Type": "application/json"})
validator(response, headers={"content-type": "application/json"})
print("✅ 响应头验证通过!")
6.5 实际应用示例
import pytest
import requests
from responses_validator import validator
class TestHeadersValidation:
"""响应头验证测试类"""
def test_content_type(self):
"""验证内容类型"""
response = requests.get("https://api.example.com/users")
validator(
response,
headers={
"content-type": "application/json*"
}
)
def test_cors_headers(self):
"""验证 CORS 响应头"""
response = requests.options("https://api.example.com/users")
validator(
response,
headers={
"access-control-allow-origin": "*",
"access-control-allow-methods": {
"value": ".*GET.*POST.*",
"mode": "re",
"msg": "CORS 配置不正确"
}
}
)
def test_rate_limit_headers(self):
"""验证限流响应头"""
response = requests.get("https://api.example.com/users")
validator(
response,
headers={
"x-rate-limit-remaining": {
"value": "lambda x: int(x) > 0",
"mode": "function",
"msg": "API 调用次数限制已用完"
},
"x-rate-limit-reset": {
"value": "lambda x: int(x) > 0",
"mode": "function",
"msg": "限流重置时间无效"
}
}
)
7. Cookies 验证(cookies)
Cookies 验证与响应头验证完全相同,每个 Cookie 字段都支持文本验证的所有模式。
7.1 简单键值匹配
cookies:
session_id: "*"
user_token: "abc*"
Python 代码示例:
import requests
from responses_validator import validator
def test_cookies_simple():
"""简单 Cookies 验证"""
response = requests.post("https://api.example.com/login", json={"username": "test"})
validator(
response,
cookies={
"session_id": "*",
"user_token": "abc*"
}
)
print("✅ Cookies 验证通过!")
7.2 详细配置模式
7.2.1 使用正则表达式验证 Cookie 格式
cookies:
session_id:
value: "*"
mode: glob
msg: "Session ID 不能为空"
user_token:
value: "[a-f0-9]{32}"
mode: re
msg: "用户 Token 格式不正确"
Python 代码示例:
import requests
from responses_validator import validator
def test_cookies_regex():
"""使用正则表达式验证 Cookies"""
response = requests.post("https://api.example.com/login", json={"username": "test"})
validator(
response,
cookies={
"session_id": {
"value": "*",
"mode": "glob",
"msg": "Session ID 不能为空"
},
"user_token": {
"value": "[a-f0-9]{32}",
"mode": "re",
"msg": "用户 Token 格式不正确(必须是 32 位十六进制字符串)"
}
}
)
print("✅ Cookies 验证通过!")
7.2.2 使用自定义函数验证 Cookie 值
cookies:
expires:
value: "lambda x: int(x) > 1234567890"
mode: function
msg: "Cookie 必须未过期"
Python 代码示例:
import requests
from responses_validator import validator
import time
def test_cookies_function():
"""使用自定义函数验证 Cookies"""
response = requests.post("https://api.example.com/login", json={"username": "test"})
current_timestamp = int(time.time())
validator(
response,
cookies={
"expires": {
"value": f"lambda x: int(x) > {current_timestamp}",
"mode": "function",
"msg": "Cookie 必须未过期"
}
}
)
print("✅ Cookies 验证通过!")
7.3 实际应用示例
import pytest
import requests
from responses_validator import validator
class TestCookiesValidation:
"""Cookies 验证测试类"""
def test_login_sets_session(self):
"""验证登录后设置 Session Cookie"""
response = requests.post(
"https://api.example.com/login",
json={"username": "test", "password": "123456"}
)
validator(
response,
cookies={
"session_id": {
"value": "*",
"mode": "glob",
"msg": "登录后必须设置 Session ID"
}
}
)
def test_secure_cookie_format(self):
"""验证安全 Cookie 格式"""
response = requests.post("https://api.example.com/login", json={"username": "test"})
validator(
response,
cookies={
"auth_token": {
"value": "^[a-zA-Z0-9]{64}$",
"mode": "re",
"msg": "认证 Token 格式不正确"
}
}
)
8. JSON 验证(json)
JSON 验证是 responses-validator 最强大的功能,支持多种验证模式。
8.1 简单部分匹配(glob 模式,默认)
默认使用 glob 模式进行部分匹配,只要响应 JSON 包含指定的字段和值即可:
json:
id: 1
name: "John"
说明:实际响应可以包含其他字段,只要包含 id: 1 和 name: "John" 即可。
Python 代码示例:
import requests
from responses_validator import validator
def test_json_glob():
"""使用 glob 模式验证 JSON(部分匹配)"""
response = requests.get("https://api.example.com/users/1")
# 验证响应 JSON 中包含 id=1 和 name="John"
# 实际响应可以是:{"id": 1, "name": "John", "email": "john@example.com"}
validator(response, json={"id": 1, "name": "John"})
print("✅ JSON 验证通过!")
8.2 数组部分匹配
对于数组,也可以进行部分匹配:
json:
users:
- id: 1
name: "John"
说明:实际数组可以包含更多元素,只要包含指定的元素即可。
Python 代码示例:
import requests
from responses_validator import validator
def test_json_array():
"""验证 JSON 数组"""
response = requests.get("https://api.example.com/users")
# 验证 users 数组中包含 id=1, name="John" 的元素
validator(
response,
json={
"users": [
{"id": 1, "name": "John"}
]
}
)
print("✅ JSON 验证通过!")
8.3 精确匹配(same 模式)
如果需要验证 JSON 必须完全匹配,使用 same 模式:
json:
value:
id: 1
name: "John"
email: "john@example.com"
mode: same # 精确匹配
msg: "JSON 结构和内容必须完全相同"
Python 代码示例:
import requests
from responses_validator import validator
def test_json_exact():
"""精确匹配 JSON"""
response = requests.get("https://api.example.com/users/1")
validator(
response,
json={
"value": {
"id": 1,
"name": "John",
"email": "john@example.com"
},
"mode": "same",
"msg": "JSON 结构和内容必须完全相同"
}
)
print("✅ JSON 验证通过!")
8.4 JSON Schema 验证(schema 模式)
使用 schema 模式可以验证 JSON 的结构是否符合某个 Schema,而不关心具体的值:
json:
value:
id: 99999
name: "string"
email: "email@example.com"
mode: schema
msg: "JSON 必须符合相同的 Schema"
说明:schema 模式会验证实际 JSON 和期望 JSON 具有相同的结构(字段类型、是否必需等),但具体值可以不同。
Python 代码示例:
import requests
from responses_validator import validator
def test_json_schema():
"""使用 Schema 模式验证 JSON 结构"""
response = requests.get("https://api.example.com/users/1")
validator(
response,
json={
"value": {
"id": 99999, # 示例值,实际可以是任何整数
"name": "string", # 示例值,实际可以是任何字符串
"email": "email@example.com" # 示例值,实际可以是任何字符串
},
"mode": "schema",
"msg": "JSON 必须符合相同的 Schema"
}
)
print("✅ JSON Schema 验证通过!")
8.5 JSONPath 验证(jsonpath 模式)
使用 jsonpath 模式可以通过 JSONPath 表达式查询 JSON 数据并验证结果:
json:
value:
"$.users[*].id": [1, 2, 3]
"$.users[0].name": ["John"]
"$.total": 3
mode: jsonpath
msg: "JSONPath 查询结果不符合预期"
说明:
- 键是 JSONPath 表达式
- 值是期望的结果列表
- 如果值不是列表,会自动转换为列表
Python 代码示例:
import requests
from responses_validator import validator
def test_json_jsonpath():
"""使用 JSONPath 验证 JSON"""
response = requests.get("https://api.example.com/users")
validator(
response,
json={
"value": {
"$.users[*].id": [1, 2, 3], # 所有用户的 ID
"$.users[0].name": ["John"], # 第一个用户的名称
"$.total": 3 # 总数(会自动转换为 [3])
},
"mode": "jsonpath",
"msg": "JSONPath 查询结果不符合预期"
}
)
print("✅ JSONPath 验证通过!")
JSONPath 表达式示例:
# 示例响应 JSON
{
"status": "ok",
"data": {
"users": [
{"id": 1, "name": "John", "age": 25},
{"id": 2, "name": "Jane", "age": 30}
],
"total": 2
}
}
# JSONPath 表达式示例
validator(
response,
json={
"value": {
"$.status": ["ok"], # 根级别的 status
"$.data.users[*].id": [1, 2], # 所有用户的 ID
"$.data.users[0].name": ["John"], # 第一个用户的名称
"$.data.total": [2] # 总数
},
"mode": "jsonpath"
}
)
8.6 KeyPath 验证(keypath 模式)
keypath 模式类似于 JSONPath,但语法更简单,并且可以对每个字段使用不同的文本验证模式:
json:
value:
"users[0].name": "John" # 这个字段使用文本 glob 模式
"data.status": # 这个字段使用文本 function 模式
value: "lambda data: data == 'active'"
mode: function
mode: keypath
msg: "KeyPath 验证失败"
Python 代码示例:
import requests
from responses_validator import validator
def test_json_keypath():
"""使用 KeyPath 验证 JSON"""
response = requests.get("https://api.example.com/users/1")
validator(
response,
json={
"value": {
"users[0].name": "John", # 简单文本验证
"data.status": { # 详细文本验证
"value": "lambda data: data == 'active'",
"mode": "function"
}
},
"mode": "keypath",
"msg": "KeyPath 验证失败"
}
)
print("✅ KeyPath 验证通过!")
KeyPath 与 JSONPath 的区别:
| 特性 | JSONPath | KeyPath |
|---|---|---|
| 语法 | $.users[*].id |
users[0].name |
| 复杂度 | 复杂,功能强大 | 简单,易于理解 |
| 结果 | 列表 | 字符串 |
| 验证方式 | 所有字段都是相等验证 | 每个字段可以使用不同的文本验证模式 |
| 适用场景 | 复杂查询、批量验证 | 简单字段验证、需要不同验证模式 |
8.7 自定义函数验证(function 模式)
使用 function 模式可以编写自定义的验证函数:
8.7.1 Lambda 表达式
json:
value: "lambda data: data.get('id', 0) > 0"
mode: function
msg: "用户 ID 必须大于 0"
Python 代码示例:
import requests
from responses_validator import validator
def test_json_lambda():
"""使用 Lambda 表达式验证 JSON"""
response = requests.get("https://api.example.com/users/1")
validator(
response,
json={
"value": "lambda data: data.get('id', 0) > 0",
"mode": "function",
"msg": "用户 ID 必须大于 0"
}
)
print("✅ JSON Lambda 验证通过!")
8.7.2 模块函数
如果验证逻辑比较复杂,可以将其提取到单独的模块中:
步骤一:创建验证函数模块
创建 validators.py 文件:
# validators.py
def validate_user_response(data):
"""验证用户响应数据"""
# 检查必需字段
if 'id' not in data or 'name' not in data or 'email' not in data:
return False
# 检查 ID 是否为正整数
if not isinstance(data['id'], int) or data['id'] <= 0:
return False
# 检查邮箱格式
if '@' not in data['email']:
return False
return True
def validate_users_list(data):
"""验证用户列表响应数据"""
if 'users' not in data:
return False
if not isinstance(data['users'], list):
return False
if len(data['users']) == 0:
return False
# 验证每个用户都有必需的字段
for user in data['users']:
if 'id' not in user or 'name' not in user:
return False
return True
步骤二:在验证中使用
json:
value: "validators.validate_user_response"
mode: function
msg: "用户响应验证失败"
Python 代码示例:
import requests
from responses_validator import validator
def test_json_module_function():
"""使用模块函数验证 JSON"""
response = requests.get("https://api.example.com/users/1")
validator(
response,
json={
"value": "validators.validate_user_response",
"mode": "function",
"msg": "用户响应验证失败"
}
)
print("✅ JSON 模块函数验证通过!")
8.8 JSON 验证模式对比
| 模式 | 用途 | 适用场景 |
|---|---|---|
| glob | 部分匹配 | 验证响应包含某些字段和值 |
| same | 精确匹配 | 验证响应完全匹配 |
| schema | Schema 验证 | 验证响应结构,不关心具体值 |
| jsonpath | JSONPath 查询 | 复杂查询、批量验证 |
| keypath | KeyPath 验证 | 简单字段验证、需要不同验证模式 |
| function | 自定义函数 | 复杂业务逻辑验证 |
8.9 实际应用示例
import pytest
import requests
from responses_validator import validator
class TestJSONValidation:
"""JSON 验证测试类"""
def test_user_response_structure(self):
"""验证用户响应结构"""
response = requests.get("https://api.example.com/users/1")
# 使用 glob 模式验证部分字段
validator(
response,
json={
"id": 1,
"name": "*",
"email": "*@*"
}
)
def test_users_list_schema(self):
"""验证用户列表 Schema"""
response = requests.get("https://api.example.com/users")
# 使用 schema 模式验证结构
validator(
response,
json={
"value": {
"users": [
{"id": 0, "name": "string", "email": "string"}
],
"total": 0
},
"mode": "schema",
"msg": "用户列表结构不正确"
}
)
def test_user_ids_with_jsonpath(self):
"""使用 JSONPath 验证用户 ID"""
response = requests.get("https://api.example.com/users")
# 使用 jsonpath 模式
validator(
response,
json={
"value": {
"$.users[*].id": [1, 2, 3],
"$.total": [3]
},
"mode": "jsonpath",
"msg": "用户 ID 列表不正确"
}
)
def test_complex_validation(self):
"""复杂验证示例"""
response = requests.get("https://api.example.com/users/1")
# 使用自定义函数验证
validator(
response,
json={
"value": "lambda data: data.get('id', 0) > 0 and len(data.get('name', '')) > 0 and '@' in data.get('email', '')",
"mode": "function",
"msg": "用户数据验证失败"
}
)
9. 函数验证(function)
函数验证允许你编写自定义函数来验证整个 Response 对象,适用于复杂的验证需求。
9.1 Lambda 表达式验证
最简单的函数验证方式是使用 Lambda 表达式:
# 验证状态码
function: "lambda resp: resp.status_code == 200"
# 验证状态码范围
function: "lambda resp: 200 <= resp.status_code < 300"
# 验证 JSON 数据
function: "lambda resp: resp.json().get('status') == 'success'"
# 验证数组长度
function: "lambda resp: len(resp.json().get('data', [])) > 0"
# 验证文本内容
function: "lambda resp: 'error' not in resp.text.lower()"
# 复合条件验证
function: "lambda resp: resp.status_code == 200 and resp.json().get('total', 0) > 10"
Python 代码示例:
import requests
from responses_validator import validator
def test_function_lambda_status_code():
"""使用 Lambda 验证状态码"""
response = requests.get("https://api.example.com/users")
validator(
response,
function="lambda resp: resp.status_code == 200"
)
print("✅ 函数验证通过!")
def test_function_lambda_status_range():
"""使用 Lambda 验证状态码范围"""
response = requests.get("https://api.example.com/users")
validator(
response,
function="lambda resp: 200 <= resp.status_code < 300"
)
print("✅ 函数验证通过!")
def test_function_lambda_json():
"""使用 Lambda 验证 JSON 数据"""
response = requests.get("https://api.example.com/users")
validator(
response,
function="lambda resp: resp.json().get('status') == 'success'"
)
print("✅ 函数验证通过!")
def test_function_lambda_array_length():
"""使用 Lambda 验证数组长度"""
response = requests.get("https://api.example.com/users")
validator(
response,
function="lambda resp: len(resp.json().get('data', [])) > 0"
)
print("✅ 函数验证通过!")
def test_function_lambda_text():
"""使用 Lambda 验证文本内容"""
response = requests.get("https://api.example.com/status")
validator(
response,
function="lambda resp: 'error' not in resp.text.lower()"
)
print("✅ 函数验证通过!")
def test_function_lambda_complex():
"""使用 Lambda 进行复合条件验证"""
response = requests.get("https://api.example.com/users")
validator(
response,
function="lambda resp: resp.status_code == 200 and resp.json().get('total', 0) > 10"
)
print("✅ 函数验证通过!")
9.2 模块函数验证
对于复杂的验证逻辑,可以将其提取到单独的模块中:
步骤一:创建验证函数模块
创建 my_funcs.py 文件:
# my_funcs.py
def ret_true(resp):
"""总是返回 True(示例函数)"""
print(f"调用 ret_true: resp={resp}")
return True
def ret_false(resp):
"""总是返回 False(示例函数)"""
print(f"调用 ret_false: resp={resp}")
return False
def validate_response_time(resp):
"""验证响应时间"""
if hasattr(resp, 'elapsed'):
elapsed_seconds = resp.elapsed.total_seconds()
return elapsed_seconds < 2.0
return False
def validate_user_response(resp):
"""验证用户响应"""
if resp.status_code != 200:
return False
try:
data = resp.json()
# 验证必需字段
if 'id' not in data or 'name' not in data:
return False
# 验证 ID 是否为正整数
if not isinstance(data['id'], int) or data['id'] <= 0:
return False
return True
except:
return False
def validate_users_list_response(resp):
"""验证用户列表响应"""
if resp.status_code != 200:
return False
try:
data = resp.json()
if 'users' not in data:
return False
if not isinstance(data['users'], list):
return False
if len(data['users']) == 0:
return False
return True
except:
return False
步骤二:在验证中使用
# 导入模块函数
function: "my_funcs.validate_user_response"
# 验证响应时间
function: "my_funcs.validate_response_time"
Python 代码示例:
import requests
from responses_validator import validator
def test_function_module():
"""使用模块函数验证响应"""
response = requests.get("https://api.example.com/users/1")
validator(
response,
function="my_funcs.validate_user_response"
)
print("✅ 函数验证通过!")
def test_function_response_time():
"""验证响应时间"""
response = requests.get("https://api.example.com/users")
validator(
response,
function="my_funcs.validate_response_time"
)
print("✅ 响应时间验证通过!")
9.3 函数验证的注意事项
9.3.1 函数签名
函数验证函数必须:
- 接受一个位置参数(
resp),类型为requests.Response或httpx.Response - 返回一个布尔值:
True表示验证通过,False表示验证失败
def my_validator(resp):
"""自定义验证函数"""
# resp 是 Response 对象
# 返回 True 表示验证通过,False 表示验证失败
return resp.status_code == 200
9.3.2 Lambda 表达式的安全限制
Lambda 表达式在受限环境中执行,只能使用以下内置函数:
基本类型:
len,str,int,float,boollist,dict,tuple,set
数学函数:
abs,max,min,sum
逻辑函数:
any,all
其他安全函数:
sorted,reversed,enumerate,zip,rangeisinstance,hasattr,getattr
允许的模块:
re(用于正则表达式)
不允许的操作:
- 文件操作
- 网络请求
- 导入其他模块(除了
re) - 执行系统命令
9.4 实际应用示例
import pytest
import requests
from responses_validator import validator
class TestFunctionValidation:
"""函数验证测试类"""
def test_response_time(self):
"""验证响应时间"""
response = requests.get("https://api.example.com/users")
validator(
response,
function="lambda resp: resp.elapsed.total_seconds() < 2.0"
)
def test_status_and_data(self):
"""验证状态码和数据"""
response = requests.get("https://api.example.com/users")
validator(
response,
function="lambda resp: resp.status_code == 200 and len(resp.json().get('data', [])) > 0"
)
def test_error_not_in_response(self):
"""验证响应中不包含错误"""
response = requests.get("https://api.example.com/status")
validator(
response,
function="lambda resp: 'error' not in resp.text.lower()"
)
def test_complex_business_logic(self):
"""复杂业务逻辑验证"""
response = requests.get("https://api.example.com/users/1")
# 使用模块函数进行复杂验证
validator(
response,
function="my_funcs.validate_user_response"
)
10. 完整示例
10.1 完整的 YAML 验证配置示例
创建一个完整的验证配置文件 complete_validation.yaml:
# complete_validation.yaml
# 状态码验证:可以是 200 或 201
status_code: "200|201"
# 响应头验证
headers:
# 简单配置
content-type: "application/json*"
# 详细配置
server:
value: "nginx.*"
mode: re
msg: "必须是 nginx 服务器"
# 自定义函数验证
x-rate-limit-remaining:
value: "lambda x: int(x) > 10"
mode: function
msg: "API 调用次数限制不足"
# Cookies 验证
cookies:
session_id: "*"
auth_token:
value: "[a-f0-9]{64}"
mode: re
msg: "认证 Token 格式不正确"
# 文本验证
text:
value: "*success*"
mode: glob
msg: "响应文本必须包含 success"
# JSON 验证(使用 JSONPath)
json:
value:
"$.data[*].id": [1, 2, 3]
"$.meta.total": [3]
"$.status": ["ok"]
mode: jsonpath
msg: "数据结构和内容验证失败"
# 函数验证(验证响应时间)
function: "lambda resp: resp.elapsed.total_seconds() < 2.0"
10.2 在 pytest 中使用完整配置
import pytest
import requests
from responses_validator import validator
from yaml import safe_load
import os
class TestCompleteAPI:
"""完整 API 测试类"""
@pytest.fixture
def validation_config(self):
"""加载验证配置"""
file_path = os.path.join(os.path.dirname(__file__), 'complete_validation.yaml')
with open(file_path, 'r', encoding='utf-8') as f:
return safe_load(f)
def test_create_user_complete(self, validation_config):
"""完整的用户创建测试"""
# 准备请求数据
user_data = {
"name": "张三",
"email": "zhangsan@example.com",
"password": "123456"
}
# 发送请求
response = requests.post(
"https://api.example.com/users",
json=user_data
)
# 使用完整配置进行验证
validator(response, **validation_config)
print("✅ 完整验证通过!")
def test_get_users_complete(self, validation_config):
"""完整的用户列表获取测试"""
# 发送请求
response = requests.get("https://api.example.com/users")
# 使用完整配置进行验证
validator(response, **validation_config)
print("✅ 完整验证通过!")
10.3 数据驱动测试示例
结合 pytest 的参数化功能,可以实现数据驱动的测试:
步骤一:创建测试数据文件 test_data.yaml:
# test_data.yaml
test_cases:
- name: "创建用户成功"
url: "https://api.example.com/users"
method: "POST"
data:
name: "张三"
email: "zhangsan@example.com"
validation:
status_code: "200|201"
json:
id: "*"
name: "张三"
- name: "获取用户列表"
url: "https://api.example.com/users"
method: "GET"
validation:
status_code: 200
json:
users: "*"
total: "*"
- name: "获取单个用户"
url: "https://api.example.com/users/1"
method: "GET"
validation:
status_code: 200
json:
id: 1
name: "*"
步骤二:创建测试文件:
import pytest
import requests
from responses_validator import validator
from yaml import safe_load
import os
def load_test_data():
"""加载测试数据"""
file_path = os.path.join(os.path.dirname(__file__), 'test_data.yaml')
with open(file_path, 'r', encoding='utf-8') as f:
return safe_load(f)
@pytest.mark.parametrize(
"test_case",
load_test_data()['test_cases'],
ids=lambda case: case['name']
)
def test_api_data_driven(test_case):
"""数据驱动的 API 测试"""
# 获取测试数据
url = test_case['url']
method = test_case['method']
data = test_case.get('data')
validation = test_case.get('validation', {})
# 发送请求
if method.upper() == 'GET':
response = requests.get(url)
elif method.upper() == 'POST':
response = requests.post(url, json=data)
elif method.upper() == 'PUT':
response = requests.put(url, json=data)
elif method.upper() == 'DELETE':
response = requests.delete(url)
else:
pytest.fail(f"不支持的 HTTP 方法: {method}")
# 进行验证
validator(response, **validation)
print(f"✅ {test_case['name']} 验证通过!")
11. 错误处理
11.1 异常模式(默认)
默认情况下,验证失败会抛出 ResponseAssertionError 异常:
import requests
from responses_validator import validator, ResponseAssertionError
def test_with_exception():
"""验证失败时抛出异常"""
response = requests.get("https://api.example.com/users")
try:
validator(response, status_code=200)
print("✅ 验证通过!")
except ResponseAssertionError as e:
print(f"❌ 验证失败: {e}")
# 可以在这里进行错误处理,比如记录日志、发送通知等
raise # 重新抛出异常,让 pytest 捕获
11.2 非异常模式
设置 raise_exception=False 可以返回错误信息而不抛出异常:
import requests
from responses_validator import validator
def test_without_exception():
"""验证失败时不抛出异常"""
response = requests.get("https://api.example.com/users")
# 不抛出异常,返回错误字典
errors = validator(
response,
status_code=200,
raise_exception=False
)
if errors:
print("❌ 验证失败:")
for field, message in errors.items():
print(f" {field}: {message}")
# 可以在这里进行自定义的错误处理
else:
print("✅ 验证通过!")
11.3 错误信息格式
错误信息是一个字典,键是验证失败的字段名,值是对应的错误消息:
{
"status_code": "状态码验证失败: 期望 200, 实际 404",
"headers": {
"content-type": "响应头 content-type 验证失败: 期望包含 'application/json', 实际 'text/html'"
},
"json": {
"id": "JSON 字段 id 验证失败: 期望 1, 实际 2"
}
}
11.4 实际应用示例
import pytest
import requests
from responses_validator import validator, ResponseAssertionError
import logging
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class TestErrorHandling:
"""错误处理测试类"""
def test_with_logging(self):
"""验证失败时记录日志"""
response = requests.get("https://api.example.com/users")
try:
validator(response, status_code=200)
logger.info("✅ 验证通过")
except ResponseAssertionError as e:
logger.error(f"❌ 验证失败: {e}")
# 记录详细的响应信息
logger.error(f"响应状态码: {response.status_code}")
logger.error(f"响应内容: {response.text[:500]}") # 只记录前 500 个字符
raise
def test_collect_errors(self):
"""收集所有错误信息"""
response = requests.get("https://api.example.com/users")
errors = validator(
response,
status_code=200,
headers={"content-type": "application/json"},
json={"id": 1},
raise_exception=False
)
if errors:
# 收集所有错误
error_messages = []
for field, message in errors.items():
if isinstance(message, dict):
# 嵌套的错误(如 headers, json)
for sub_field, sub_message in message.items():
error_messages.append(f"{field}.{sub_field}: {sub_message}")
else:
error_messages.append(f"{field}: {message}")
# 统一处理错误
error_summary = "n".join(error_messages)
pytest.fail(f"验证失败:n{error_summary}")
12. 最佳实践
12.1 使用 YAML 配置管理验证规则
推荐做法:
# validation_rules.yaml
# 将验证规则按功能模块组织
user_api:
get_user:
status_code: 200
json:
id: "*"
name: "*"
create_user:
status_code: "200|201"
json:
id: "*"
name: "*"
list_users:
status_code: 200
json:
users: "*"
total: "*"
Python 代码:
import yaml
from responses_validator import validator
def load_validation_rules():
"""加载验证规则"""
with open('validation_rules.yaml', 'r', encoding='utf-8') as f:
return yaml.safe_load(f)
def test_user_api():
"""使用组织好的验证规则"""
rules = load_validation_rules()
response = requests.get("https://api.example.com/users/1")
validator(response, **rules['user_api']['get_user'])
12.2 选择合适的验证模式
建议:
- 简单验证:使用 glob 模式(默认)
- 精确匹配:使用 same 模式
- 结构验证:使用 schema 模式
- 复杂查询:使用 jsonpath 模式
- 业务逻辑:使用 function 模式
12.3 提供清晰的错误消息
推荐做法:
json:
value:
id: 1
mode: glob
msg: "用户 ID 必须是 1" # 提供清晰的错误消息
12.4 模块化验证函数
推荐做法:
将复杂的验证逻辑提取到单独的模块中:
# validators/user_validators.py
def validate_user_response(data):
"""验证用户响应"""
# 复杂的验证逻辑
pass
# 在验证中使用
validator(response, json={"value": "validators.user_validators.validate_user_response", "mode": "function"})
12.5 性能考虑
建议:
- 对于高频验证,优先使用简单的验证模式(glob, same)
- 避免在 Lambda 表达式中执行复杂计算
- 对于复杂验证,使用模块函数而不是 Lambda 表达式
12.6 测试组织结构
推荐的项目结构:
project/
├── tests/
│ ├── test_user_api.py
│ ├── test_product_api.py
│ └── validations/
│ ├── user_api.yaml
│ ├── product_api.yaml
│ └── common.yaml
├── validators/
│ ├── user_validators.py
│ └── common_validators.py
└── conftest.py
13. 常见问题(FAQ)
13.1 如何验证数组中的特定元素?
问题:如何验证数组中的第一个元素?
答案:使用 JSONPath 模式:
validator(
response,
json={
"value": {
"$.users[0].name": ["John"]
},
"mode": "jsonpath"
}
)
13.2 Headers 和 Cookies 是否区分大小写?
问题:响应头的键名是否区分大小写?
答案:不区分。库会自动将键名转换为小写进行匹配。Content-Type 和 content-type 是等价的。
13.3 Lambda 表达式有哪些安全限制?
问题:Lambda 表达式中可以使用哪些函数?
答案:Lambda 表达式在受限环境中执行,只能使用以下内置函数:
- 基本类型:
len,str,int,float,bool,list,dict,tuple,set - 数学函数:
abs,max,min,sum - 逻辑函数:
any,all - 其他安全函数:
sorted,reversed,enumerate,zip,range,isinstance,hasattr,getattr - 允许的模块:
re(用于正则表达式)
13.4 如何同时使用简单和详细配置?
问题:可以在同一个验证中混合使用简单和详细配置吗?
答案:可以。对于任何字段,详细配置会优先于简单配置。
headers:
content-type: "application/json" # 简单配置
server: # 详细配置
value: "nginx*"
mode: glob
msg: "服务器必须是 nginx"
13.5 jsonpath 和 keypath 有什么区别?
问题:什么时候使用 jsonpath,什么时候使用 keypath?
答案:
| 特性 | jsonpath | keypath |
|---|---|---|
| 语法 | $.users[*].id |
users[0].name |
| 复杂度 | 复杂,功能强大 | 简单,易于理解 |
| 结果 | 列表 | 字符串 |
| 验证方式 | 所有字段都是相等验证 | 每个字段可以使用不同的文本验证模式 |
| 适用场景 | 复杂查询、批量验证 | 简单字段验证、需要不同验证模式 |
建议:
- 需要复杂查询时使用 jsonpath
- 需要简单字段验证且需要不同验证模式时使用 keypath
13.6 如何处理动态值验证?
问题:如何验证动态生成的值(如时间戳、随机 ID)?
答案:使用 function 模式或自定义验证函数:
import time
from responses_validator import validator
def test_dynamic_value():
"""验证动态值"""
response = requests.get("https://api.example.com/data")
# 使用 Lambda 验证时间戳
current_time = int(time.time())
validator(
response,
json={
"value": f"lambda data: data.get('timestamp', 0) > {current_time - 60}",
"mode": "function",
"msg": "时间戳验证失败"
}
)
13.7 如何验证可选字段?
问题:如何验证一个字段可能存在也可能不存在?
答案:在 glob 模式下,只验证存在的字段。如果字段不存在,验证会失败。如果需要验证可选字段,可以使用 function 模式:
validator(
response,
json={
"value": "lambda data: 'optional_field' not in data or isinstance(data.get('optional_field'), str)",
"mode": "function",
"msg": "可选字段验证失败"
}
)
13.8 如何验证响应时间?
问题:如何验证 API 响应时间?
答案:使用 function 模式:
validator(
response,
function="lambda resp: resp.elapsed.total_seconds() < 2.0"
)
13.9 如何处理验证失败的情况?
问题:验证失败时应该如何处理?
答案:有两种方式:
-
抛出异常(默认):
try: validator(response, status_code=200) except ResponseAssertionError as e: # 处理错误 logger.error(f"验证失败: {e}") raise -
返回错误信息:
errors = validator(response, status_code=200, raise_exception=False) if errors: # 处理错误 for field, message in errors.items(): logger.error(f"{field}: {message}")
14. 总结
14.1 核心概念回顾
- responses-validator 是一个用于验证 HTTP 响应的 Python 库
- 核心优势:将验证规则与测试代码分离,使用 YAML 格式定义验证规则
- 支持多种验证模式:状态码、文本、响应头、Cookies、JSON、函数验证
- 灵活的配置方式:支持简单配置和详细配置两种方式
14.2 验证类型总结
| 验证类型 | 支持的模式 | 适用场景 |
|---|---|---|
| status_code | 精确值、通配符、多个值 | 验证 HTTP 状态码 |
| text | glob, same, re, function | 验证响应文本内容 |
| headers | glob, same, re, function | 验证响应头 |
| cookies | glob, same, re, function | 验证 Cookies |
| json | glob, same, schema, jsonpath, keypath, function | 验证 JSON 数据 |
| function | Lambda, 模块函数 | 自定义复杂验证 |
14.3 使用建议
- 优先使用 YAML 模式:对于复杂验证规则,推荐使用 YAML 配置文件
- 选择合适的验证模式:根据验证需求选择合适的模式,避免过度复杂化
- 提供清晰的错误消息:为重要的验证规则提供清晰的错误消息
- 模块化验证函数:将复杂的验证逻辑提取到单独的、可重用的函数中
- 性能考虑:对于高频验证,优先使用简单的验证模式
14.4 下一步学习
掌握了 responses-validator 的基础用法后,你可以:
- 深入学习 JSONPath:学习更复杂的 JSONPath 表达式
- 自定义验证函数:编写更复杂的自定义验证函数
- 集成到 CI/CD:将验证集成到持续集成和持续部署流程中
- 性能优化:优化验证性能,提高测试执行速度
15. 附录
15.1 完整示例代码
15.1.1 基础示例
import pytest
import requests
from responses_validator import validator
def test_basic_validation():
"""基础验证示例"""
response = requests.get("https://api.example.com/users/1")
validator(
response,
status_code=200,
headers={"content-type": "application/json"},
json={"id": 1, "name": "*"}
)
15.1.2 YAML 配置示例
# validation.yaml
status_code: 200
headers:
content-type: "application/json"
json:
id: 1
name: "*"
import pytest
import requests
from responses_validator import validator
from yaml import safe_load
def test_yaml_validation():
"""YAML 配置验证示例"""
with open('validation.yaml', 'r', encoding='utf-8') as f:
config = safe_load(f)
response = requests.get("https://api.example.com/users/1")
validator(response, **config)
15.2 常用验证模式速查表
| 验证需求 | 配置方式 | 示例 |
|---|---|---|
| 状态码等于 200 | status_code: 200 |
精确匹配 |
| 状态码是 2xx | status_code: "2*" |
通配符 |
| 状态码是 200 或 201 | status_code: "200|201" |
多个值 |
| 文本包含 “success” | text: "*success*" |
glob 模式 |
| 文本精确匹配 | text: {value: "...", mode: same} |
same 模式 |
| 响应头包含 JSON | headers: {content-type: "application/json*"} |
glob 模式 |
| JSON 包含字段 | json: {id: 1} |
glob 模式 |
| JSON 精确匹配 | json: {value: {...}, mode: same} |
same 模式 |
| JSON Schema 验证 | json: {value: {...}, mode: schema} |
schema 模式 |
| JSONPath 查询 | json: {value: {"$.users[*].id": [1,2]}, mode: jsonpath} |
jsonpath 模式 |
| 自定义验证 | function: "lambda resp: ..." |
function 模式 |
15.3 参考资源
- 官方文档:https://pypi.org/project/responses-validator/
- GitHub 仓库:https://github.com/dongfangtianyu/responses-validator
- JSONPath 教程:https://goessner.net/articles/JsonPath/
- YAML 语法:https://yaml.org/spec/
文档结束
希望这份详细的文档能够帮助你全面掌握 responses-validator 的使用方法!如果你在学习过程中遇到任何问题,欢迎查阅官方文档或寻求帮助。