Contract Test
解决什么问题:服务间接口是"契约"——不验证契约 = 上线即爆。契约测试让 Provider 和 Consumer 各自独立验证接口约束,不依赖端到端集成。
它是什么
Contract Test(契约测试) 验证服务边界的接口契约——
- Provider 侧:声明"我提供这个 schema"
- Consumer 侧:声明"我消费这个 schema"
- 共享:Provider 跑 Consumer 的契约,验证所有 Consumer 期望都满足
EDM Ch 6:"Contracts are first-class artifacts in event-driven systems."
SE@G Ch 11:"Integration tests are slow and flaky. Contract tests give you confidence without the cost."
V2 视角(V2.7 B4 抽象):契约 = 服务接口的抽象。Provider / Consumer 用契约解耦——契约测试是解耦的工程保障。
关键属性
| 属性 | 值/含义 |
|---|---|
| 两种方向 | Consumer-Driven(CDC)/ Provider-Driven |
| 形式 | OpenAPI / Pact / Avro Schema / Protobuf |
| 位置 | Provider 仓库 + Consumer 仓库共享同一份契约 |
| 运行 | CI 中执行,不依赖真集成环境 |
| 反模式 | 把契约测试当集成测试(启动完整服务) |
| 核心约束 | 契约变更 = breaking change = 跨团队沟通 |
| 判错标准 | 接口改了 Consumer 不知道 = 没契约测试 |
怎么用
场景 1:REST API 契约(Pact / OpenAPI)
Consumer 侧:
// Consumer 写期望:当我 GET /users/123 时返回什么
const interaction = {
state: "user 123 exists",
uponReceiving: "a request for user 123",
withRequest: { method: "GET", path: "/users/123" },
willRespondWith: {
status: 200,
body: { id: 123, name: "Alice" }
}
};Provider 侧:跑 Consumer 上传的契约,验证真实 API 满足所有期望。
场景 2:事件契约(Avro / Protobuf)
Producer 发布 schema(Avro IDL):
record OrderCreated {
string orderId;
string customerId;
timestamp createdAt;
array<OrderItem> items;
}Consumer 验证:自己写的反序列化代码能正确解析历史 schema 集合——Schema 演进不破坏旧 Consumer(EDM Ch 6)。
场景 3:Consumer-Driven Contract(CDC)
关键原则:Consumer 主导契约——Consumer 才是需求的真实来源:
- Consumer 写"我期望的契约"
- 上传到 Pact Broker
- Provider 在 CI 中跑"能否满足所有 Consumer 期望"
- Provider 想改契约 = 必须先跟 Consumer 沟通
V2 B3 视角:CDC = 需求侧主导 = "按对象分解" 在接口层的反转。
常见误区
- "契约测试 = 集成测试"——错。契约测试不启动服务,用 mock 验证 schema
- "Provider 自己写契约"——错。Provider 写的契约是 Provider 视角,不是 Consumer 视角
- "契约=OpenAPI 文档"——错。文档是描述,契约是机器可验证的断言
- "契约不变就永远安全"——错。Schema 必须有演进规则——加字段行,删字段不行(EDM Ch 6)
- "端到端测试能替代契约测试"——错。端到端慢、脆、难定位;契约测试快、稳、定位精准
关键洞察
契约测试是服务边界的"控制论接口"——它是 Provider 和 Consumer 共用的状态方程。
控制论视角:接口 = 系统的输入输出端口;契约 = 端口的传递函数。没有传递函数 = 控制器无法设计。 IDDD Ch 13 视角:BC 之间的集成(REST/消息)必须用契约显式约束——这是 Open Host Service 的工程化。 SE@G Ch 11 视角:契约测试替代部分集成测试,规模化下 ROI 极高。 EDM Ch 6 视角:事件 schema 是异步系统的契约——schema 演进是异步系统的头等大事。
相关链接
- Test Pyramid——契约测试在金字塔中的位置
- Domain Model Test——领域层独立测试
- [V3 涌现作为] · 抽象——契约 = 接口抽象
- [V3 涌现作为] · 权衡——契约粒度的权衡
- 源典:IDDD Ch 13——BC 集成的契约
- 源典:EDM Ch 6——事件 schema 演进