Skip to content

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 侧:

typescript
// 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):

avro
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 才是需求的真实来源:

  1. Consumer 写"我期望的契约"
  2. 上传到 Pact Broker
  3. Provider 在 CI 中跑"能否满足所有 Consumer 期望"
  4. Provider 想改契约 = 必须先跟 Consumer 沟通

V2 B3 视角:CDC = 需求侧主导 = "按对象分解" 在接口层的反转。

常见误区 ​

  1. "契约测试 = 集成测试"——错。契约测试不启动服务,用 mock 验证 schema
  2. "Provider 自己写契约"——错。Provider 写的契约是 Provider 视角,不是 Consumer 视角
  3. "契约=OpenAPI 文档"——错。文档是描述,契约是机器可验证的断言
  4. "契约不变就永远安全"——错。Schema 必须有演进规则——加字段行,删字段不行(EDM Ch 6)
  5. "端到端测试能替代契约测试"——错。端到端慢、脆、难定位;契约测试快、稳、定位精准

关键洞察 ​

契约测试是服务边界的"控制论接口"——它是 Provider 和 Consumer 共用的状态方程。

控制论视角:接口 = 系统的输入输出端口;契约 = 端口的传递函数。没有传递函数 = 控制器无法设计。 IDDD Ch 13 视角:BC 之间的集成(REST/消息)必须用契约显式约束——这是 Open Host Service 的工程化。 SE@G Ch 11 视角:契约测试替代部分集成测试,规模化下 ROI 极高。 EDM Ch 6 视角:事件 schema 是异步系统的契约——schema 演进是异步系统的头等大事。

相关链接 ​

从名家方法论与工程化思路中蒸馏出自己的工程体系。