← 中文资源

简体中文版本

消费者驱动的契约测试落地工作流

渐进落地服务间契约测试:发布消费者期望,CI 里让提供方对照验证,再退役脆弱的集成测试。

阅读英文原文

目标

靠“把所有服务部署到一起”来验证集成,又慢又脆,而且只能在合并后发现破裂。消费者契约在各自服务的 CI 内、用几秒钟验证同一个事实——提供方仍然满足消费方的期望——并在任何人合并之前拦住破坏。

步骤要点

  1. 选最痛的集合作试点:从引发事故最多的服务对开始,而不是最简单的那对,程序必须先在真实痛点上证明价值,两个团队都要同意。
  2. 消费方先写契约:把依赖的交互(请求形态、响应字段、状态语义)定义为可执行的契约测试,失败的测试就是期望声明,契约发布到 broker。
  3. 提供方对照验证:提供方 CI 拉取已发布契约并在运行实例上重放,任何分歧都让构建失败在合并之前。
  4. 退役等价的端到端测试:契约覆盖该交互后,删除需要两个服务同时部署的对应 E2E 用例,流水线时长可见下降。
  5. 一对一对循环扩展:对下一个集成重复“定义—发布—验证—退役”,每次控制在一周内完成。

排错提示

契约越写越多 E2E 一条没删是只加不减,每覆盖一个交互就删对应的多服务用例;试点挑了最简单的对说服不了任何人,用事故史选最痛的,第一次拦截就是最好的广告;提供方 CI 没拉契约等于只有一半流程,broker 的 webhook 要真接进流水线。

适用边界

契约测试验证接口兼容性而非业务语义正确性,关键链路仍需少量端到端冒烟;契约维护成本随消费者数量增长,接口设计要有版本纪律配合。

代码示例

pair: web (consumer) -> orders-api (provider)

consumer: web
  contract: GET /orders/{id} -> 200 {id, total_cents, status}
  test: expects total_cents > 0 for fixture order
  -> publishes contract v3 to broker

provider: orders-api CI
  fetches web@v3 contract
  replays against running instance:
    GET /orders/demo-1 -> 200 {total_cents: -5}  FAIL
  build blocked BEFORE merge

retired: e2e_checkout_full (needed web+orders+db+cache)
  pipeline: 41 min -> 27 min