测试边界,而不是整个世界
启动五个服务的端到端测试既慢又容易因无关原因失败。契约测试把边界隔离出来:消费者记录自己的需求,提供者验证能否满足这些期望,于是得到一条快速、聚焦、可同时跑在双方流水线里的检查。
{
"consumer": "web-checkout",
"provider": "orders-api",
"interaction": "get order",
"request": { "method": "GET", "path": "/orders/42" },
"response": {
"status": 200,
"body": { "id": "42", "status": "paid", "total": 4200 }
}
}
这是 Pact 风格的契约。工具细节各异,关键点是期望被版本化并由提供者验证。
覆盖错误和可选性
只检查成功响应的契约,会漏掉客户端在失败时依赖的形状。应包含未找到、校验错误和授权失败等响应。字段是可选还是必填要有意声明:一个字段变成可空,就可能破坏假设它总是字符串的消费者。契约测试还应断言内容类型和状态码,而不只是响应体。
保持诚实
即使提供者通过契约测试,生产环境仍可能因为基础设施、超时或数据差异而出问题。契约测试用于接口兼容性,关键流程还应保留少量端到端测试。从消费者流水线发布契约,在提供者流水线中验证,并在验证失败时阻止部署。无人验证的契约只是文档。
何时使用
当许多消费者依赖同一服务,而完整集成环境又昂贵时,使用契约测试。优点是反馈快、目标明确、接口显式;代价是契约维护成本,以及真实基础设施相关覆盖不足。与端到端测试相比,它更早发现接口漂移,但不能证明整个系统可用。