微服务测试策略:契约测试与集成测试思路

微服务让"测试"变得更难:一个功能跨多个服务与中间件,本地起不全、环境依赖多、团队并行开发时接口说变就变。测试策略的目标不是消灭手工验证,而是用分层手段让"接口不一致""依赖没就绪"这类问题尽早暴露在 CI 里。本章给出分层思路,重点讲契约测试。

分层测试全景

按成本与覆盖范围分为四层:单元测试(只测一个类/方法,依赖用 Mock,跑得最快);集成测试(拉起真实或近真实的依赖——数据库、Redis、MQ,验证服务与依赖协作正确);契约测试(验证"服务之间接口约定"是否被双方遵守);端到端测试(全链路真实环境验证主流程)。越往下跑得越勤、越往上跑得越少:单元测试每次提交都跑,端到端放在发布前。

微服务测试的三个痛点

一是依赖编排:被测服务要连 MySQL、Redis、RabbitMQ、注册中心,本机环境各不相同,测试结果"换台机器就变"。二是接口耦合:order-service 依赖 user-service 的接口,对方还没开发完或改了字段,本方测试就被卡住。三是"各测各的":两端各自 Mock,接口真不一致时反而测不出来,上线才炸。契约测试正是针对后两个痛点。

契约测试:以接口约定为中心

消费者驱动契约的思路:服务的调用方(消费者)把"我对你的接口的期望"写成契约(请求是什么样、响应应该是什么样);提供方用契约校验自己的实现——每条契约都变成一个对提供方接口的自动测试;同时契约会生成桩(Stub)供消费者在本地测试中使用。效果是:提供方改动接口时,CI 会立刻告诉它"某某消费者依赖的约定被你破坏了",消费者不依赖提供方在线也能开发。

Spring Cloud Contract 的落地形态

Spring Cloud Contract 是官方契约测试方案:提供方工程引入 Contract Verifier 相关插件与依赖,把契约文件(Groovy 或 YAML 格式)放在约定目录,构建时自动生成两类产物——验证提供方实现的测试,以及可发布的桩(Stub);消费者工程通过 Stub Runner 在测试中启动桩服务。契约文件写法、目录约定与插件配置随版本演进,动手前以官方文档为准。

集成测试:用 Testcontainers 拉真依赖

为让"数据库差异"消失,推荐 Testcontainers:测试时用真实镜像启动 MySQL/Redis/RabbitMQ 容器,用完自动销毁。Spring Boot 3.1+ 的 @ServiceConnection 简化了连接配置:在测试里声明容器 Bean 并标注 @ServiceConnection,框架自动把数据源等配置指向容器,例如:

@Testcontainers
@SpringBootTest
class OrderServiceIT {
    @Container
    @ServiceConnection
    static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8");
}

被测服务仍走真实的 Feign/MyBatis 等组件,只是把外部依赖替换成容器实例,可信度远高于全 Mock。

外部 HTTP 依赖的本地替身:WireMock

契约桩是首选;对还没有契约的第三方服务,可用 WireMock 起一个可控的 HTTP 假服务,把 FeignClient 的 url 指向它,返回预设响应、断言请求内容。它能模拟超时、500 等异常路径,是超时重试逻辑(第 06 章)测试的好帮手。注意 WireMock 的期望要与真实接口对齐并定期 review,否则就是"自测自嗨"。

把策略落进 CI

推荐的流水线形态:每个服务提交时跑单元测试 + 契约验证(若本服务是提供方,验证其实现满足所有已发布契约;若还发布了新契约,通知相关消费者);合并前跑集成测试(Testcontainers);发布前跑关键端到端用例。契约仓库与消费者版本要配套管理,接口变更走"先改契约 → 提供方满足新契约 → 消费者切新桩"的节奏,从机制上避免"悄悄改接口"。契约文件的改动应纳入代码评审:改契约等于改接口,需要提供方与相关消费者共同确认后再合入。

测试数据与稳定性

集成测试跑不稳,团队就会慢慢放弃它,因此稳定性与覆盖面同样重要:

  • 快且隔离:容器实例复用、使用随机端口与独立测试库,用例之间互不污染,让整轮集成测试控制在分钟级;
  • 可控的时间与随机性:涉及超时、重试、定时器的用例,用可控时钟与固定数据种子,保证结果可重复,避免"昨天绿今天红";
  • 失败注入常态化:把"下游超时、返回 500、响应变慢"做成可开关的测试场景,让第 06 章与第 15 章的超时重试、熔断降级逻辑持续被验证,而不是上线前临时手搓。

小结

测试策略的骨架是"分层 + 契约 + 容器化依赖":单元测试管逻辑、集成测试管协作、契约测试管接口一致、端到端管主流程。契约测试是微服务特有的关键一环,它把"两边口头对齐"变成"CI 自动校验"。整套 Spring Cloud 能力(注册、调用、网关、容错、追踪、消息、事务)到此串完,把测试补齐,才算一个可交付的微服务工程。

笔记加载中…