介绍 Spring Cloud Contract

Spring Cloud Contract 将 TDD 提升到软件架构层面。它允许您执行消费者驱动和生产者驱动的契约测试。

历史

在成为 Spring Cloud Contract 之前,该项目名为 Accurest。它由来自 (Codearte) 的 Marcin GrzejszczakJakub Kubrynski 创建。

0.1.0 版本于 2015 年 1 月 26 日发布,并在 2016 年 2 月 29 日发布 1.0.0 版本时变得稳定。

为何需要它?

假设我们有一个由多个微服务组成的系统,如下图所示

Microservices Architecture

测试问题

如果我们想测试上一节图片左上角的应用程序,以确定它是否能与其他服务通信,我们可以做以下两件事中的一件

  • 部署所有微服务并执行端到端测试。

  • 在单元测试和集成测试中模拟其他微服务。

两者都有其优点,但也有许多缺点。

部署所有微服务并执行端到端测试

优点

  • 模拟生产环境。

  • 测试服务之间的真实通信。

缺点

  • 为了测试一个微服务,我们必须部署六个微服务、几个数据库以及其他项。

  • 测试运行的环境会被锁定,仅用于一套测试(在此期间,其他人将无法运行测试)。

  • 它们运行时间很长。

  • 反馈来得非常晚。

  • 它们极其难以调试。

在单元测试和集成测试中模拟其他微服务

优点

  • 它们提供非常快的反馈。

  • 它们没有基础设施要求。

缺点

  • 服务实现者创建的 stub 可能与实际情况毫无关系。

  • 即使测试通过了,生产环境仍可能失败,而您可能会带着通过的测试上线。

为了解决上述问题,Spring Cloud Contract 应运而生。其主要思想是为您提供非常快速的反馈,而无需搭建整个微服务环境。如果您使用 stub 进行开发,那么您唯一需要的应用程序是您自己的应用程序直接使用的那些。下图展示了 stub 与应用程序的关系

Stubbed Services

Spring Cloud Contract 让您确信所使用的 stub 是由您调用的服务创建的。此外,如果您能够使用它们,这意味着它们已经在生产者端进行了测试。简而言之,您可以信任这些 stub。

目的

Spring Cloud Contract 的主要目的包括

  • 确保 HTTP 和消息传递 stub(在开发客户端时使用)与实际的服务器端实现完全一致。

  • 推广 ATDD(验收测试驱动开发)方法和微服务架构风格。

  • 提供一种发布契约变更的方式,使双方能够立即看到变更。

  • 生成可在服务器端使用的样板测试代码。

默认情况下,Spring Cloud Contract 与 Wiremock 集成,作为 HTTP 服务器 stub。

Spring Cloud Contract 的目的不是开始在契约中编写业务功能。假设我们有一个欺诈检查的业务用例。如果用户可能因 100 种不同原因而被视为欺诈,我们假设您会创建两个契约,一个用于正面情况,一个用于负面情况。契约测试用于测试应用程序之间的契约,而不是模拟完整行为。

什么是契约?

作为服务的消费者,我们需要定义我们到底想要达到什么目标。我们需要明确我们的期望。这就是我们编写契约的原因。换句话说,契约是对 API 或消息通信应该如何表现的约定。考虑以下示例

假设您想发送一个包含客户公司 ID 和希望向我们借款金额的请求。您还希望使用 PUT 方法将其发送到 /fraudcheck URL。以下列表展示了一个检查客户是否应被标记为欺诈的契约,包括 Groovy 和 YAML 格式

预期契约来自可信来源。您绝不应下载或使用来自不可信位置的契约。