首页教程 › JSON接口测试
测试实践 · 原创指南

JSON 接口测试实战:从契约验证到异常用例

发布于 2026-07-13 · 阅读约 12 分钟 · 适合后端、前端与测试工程师

接口返回了 HTTP 200,并不代表接口真的正确。字段类型变化、可选字段突然消失、错误响应结构不一致,都可能让客户端在上线后崩溃。有效的 JSON 接口测试应同时检查语法、数据契约、业务约束和兼容性。

本文解决什么问题
  1. 建立四层测试模型
  2. 验证响应契约
  3. 设计边界与异常用例
  4. 正确使用快照测试
  5. 检查隐私与敏感字段
  6. 发布前检查清单

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. 自动检查敏感字段泄漏

除了验证“应该返回什么”,还要验证“不应该返回什么”。可以递归扫描字段名,拦截 passwordtokensecretprivateKey 等高风险键。字段名检查只是第一层,还应准备类似银行卡号、身份证号和 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 与 REST API 设计最佳实践 · JSON 安全注意事项 · 常见 JSON 错误修复