JSON 接口测试实战:从契约验证到异常用例
接口返回了 HTTP 200,并不代表接口真的正确。字段类型变化、可选字段突然消失、错误响应结构不一致,都可能让客户端在上线后崩溃。有效的 JSON 接口测试应同时检查语法、数据契约、业务约束和兼容性。
1. 四层测试模型
建议由便宜、稳定的检查开始,再逐步进入业务规则。这样失败时更容易定位原因。
| 层级 | 检查内容 | 典型失败 |
|---|---|---|
| 语法层 | 是否为合法 JSON、编码是否正确 | 尾随逗号、BOM、截断响应 |
| 结构层 | 字段、类型、必填项和嵌套关系 | id 从数字变成字符串 |
| 业务层 | 数值范围、状态组合、权限规则 | 库存为负数、无权限却返回手机号 |
| 兼容层 | 旧客户端能否忽略新增字段 | 重命名字段导致旧版解析失败 |
先用 JSON验证工具 排除语法错误,再运行契约和业务断言,能减少无意义的失败噪声。
2. 用契约约束响应,而不是比对整段文本
JSON 对象的键顺序通常没有业务意义,因此不要直接比较两段字符串。更可靠的方法是解析后检查类型和约束。下面是一份简化的用户响应契约:
{
"type": "object",
"required": ["id", "name", "status"],
"properties": {
"id": { "type": "integer", "minimum": 1 },
"name": { "type": "string", "minLength": 1 },
"status": { "enum": ["active", "disabled"] },
"tags": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
}
},
"additionalProperties": true
}
additionalProperties 是否允许要根据兼容策略决定。面向公共客户端的响应通常应允许新增字段;对内部数据导入任务,则可以采用严格模式,尽早发现意外字段。
3. 边界值和异常用例怎么设计
只测试“正常用户”远远不够。每个字段至少考虑缺失、空值、错误类型、最小值、最大值和超长值。数组还要覆盖空数组、单元素、重复元素和大数组。
// 不要只测这一种
{ "page": 1, "pageSize": 20 }
// 还应覆盖
{ "page": 0, "pageSize": 20 }
{ "page": -1, "pageSize": 20 }
{ "page": "1", "pageSize": 20 }
{ "page": 1, "pageSize": 0 }
{ "page": 1, "pageSize": 10001 }
错误响应也必须有稳定契约。推荐至少包含机器可判断的错误码、人类可读信息和请求追踪标识:
{
"error": {
"code": "INVALID_PAGE_SIZE",
"message": "pageSize 必须在 1 到 100 之间",
"requestId": "req_8f31c2"
}
}
不要在错误信息中返回 SQL、磁盘路径、访问令牌或完整堆栈。调试详情应写入受保护的服务端日志,并通过 requestId 关联。
4. 快照测试适合什么,不适合什么
快照适合发现大型响应的意外结构变化,但动态字段会制造大量误报。保存快照前,应移除时间戳、随机 ID、签名和请求追踪字段,并对对象键排序。
- 适合:固定配置、静态目录、错误响应模板。
- 谨慎使用:用户列表、搜索结果、实时价格。
- 不建议:把每次快照变化都直接点击“接受”,这会让测试失去审查价值。
5. 自动检查敏感字段泄漏
除了验证“应该返回什么”,还要验证“不应该返回什么”。可以递归扫描字段名,拦截 password、token、secret、privateKey 等高风险键。字段名检查只是第一层,还应准备类似银行卡号、身份证号和 JWT 的模式检测。
const forbidden = /password|secret|access_?token|private_?key/i;
function findSensitive(value, path = '$') {
if (!value || typeof value !== 'object') return [];
return Object.entries(value).flatMap(([key, child]) => {
const current = `${path}.${key}`;
return [
...(forbidden.test(key) ? [current] : []),
...findSensitive(child, current)
];
});
}
测试数据本身也不应复制生产环境的真实个人信息。优先使用人工构造或脱敏后的数据,并确保测试报告不会把敏感响应永久保存为附件。
6. 发布前检查清单
- 成功响应和所有主要错误响应都是合法 JSON。
Content-Type明确为application/json,字符编码一致。- 必填字段、类型、枚举和数值范围均有自动化断言。
- 缺失字段、
null、空字符串和空数组的语义已经约定。 - 新增字段不会破坏旧客户端,删除或改名字段有版本迁移方案。
- 响应中不存在密码、令牌、内部堆栈或越权个人数据。
- 大响应已测试体积、分页上限、超时和并发条件。
- 错误响应包含稳定错误码和可追踪的请求 ID。
高质量接口测试的目标不是追求用例数量,而是把契约变更、边界行为和数据泄漏在发布前暴露出来。把这份清单加入合并请求模板,比上线前临时检查更可靠。