Spring Cloud ContractSpring Cloud Contract5.0.0

Spring Cloud Contract是一个伞形项目,旨在为用户成功实现消费者驱动的契约(Consumer Driven Contracts)方法提供解决方案。目前,Spring Cloud Contract包含Spring Cloud Contract Verifier项目。

Spring Cloud Contract Verifier是一个工具,可用于JVM应用程序的消费者驱动契约(CDC)开发。它附带了用Groovy或YAML编写的契约定义语言(DSL)。契约定义用于生成以下资源

  • 默认情况下,生成JSON存根定义,供WireMock(HTTP服务器存根)在客户端代码进行集成测试(客户端测试)时使用。测试代码仍需手动编写,测试数据由Spring Cloud Contract Verifier生成。

  • 如果您正在使用消息路由,则会生成相应的路由。我们正在与Spring Integration、Spring Cloud Stream和Apache Camel集成。但是,如果您愿意,也可以设置自己的集成。

  • 验收测试(默认为JUnit或Spock),用于验证API的服务端实现是否符合契约(服务端测试)。完整的测试由Spring Cloud Contract Verifier生成。

Spring Cloud Contract Verifier将TDD提升到软件架构层面。

要了解Spring Cloud Contract如何支持其他语言,请查看https://springjava.cn/blog/2018/02/13/spring-cloud-contract-in-a-polyglot-world[这篇博客文章]。

特性

当尝试测试与其它服务通信的应用程序时,我们可以做以下两件事之一

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

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

两者都有其优点,但也有很多缺点。让我们重点关注后者。部署所有微服务并执行端到端测试

优点

  • 模拟生产环境

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

缺点

  • 要测试一个微服务,我们需要部署6个微服务、几个数据库等。

  • 进行测试的环境将被单个测试套件锁定(即,在此期间没有人能够运行测试)。

  • 运行时间长

  • 反馈非常滞后

  • 调试极其困难

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

优点

  • 反馈非常迅速

  • 没有基础设施要求

缺点

  • 服务的实现者创建存根,因此它们可能与实际情况无关

  • 您可能通过了测试,但生产环境却失败了

为了解决上述问题,Spring Cloud Contract Verifier与Stub Runner应运而生。它们的核心思想是为您提供快速反馈,而无需搭建整个微服务世界。

Spring Cloud Contract Verifier的特点

  • 确保HTTP/消息存根(在开发客户端时使用)与实际的服务端实现行为完全一致

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

  • 提供一种发布契约变更的方式,使其在通信双方立即可见

  • 在服务器端生成样板测试代码

Spring Boot 配置

[[on-the-producer-side]] = 在生产者侧

要开始使用 Spring Cloud Contract,您可以将以 Groovy DSL 或 YAML 表示的 REST 或消息契约文件添加到 contracts 目录中,该目录由 contractsDslDir 属性设置。默认情况下,它是 $rootDir/src/test/resources/contracts。

然后您可以将Spring Cloud Contract Verifier依赖和插件添加到您的构建文件中,示例如下

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-contract-verifier</artifactId>
    <scope>test</scope>
</dependency>

以下清单展示了如何添加插件,它应该放在文件中的 build/plugins 部分

<plugin>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    <version>${spring-cloud-contract.version}</version>
    <extensions>true</extensions>
</plugin>

运行./mvnw clean install会自动生成测试,以验证应用程序是否符合添加的契约。默认情况下,测试将在org.springframework.cloud.contract.verifier.tests下生成。

由于合同描述的功能尚未实现,测试会失败。

要使它们通过,您必须添加处理HTTP请求或消息的正确实现。此外,您必须为自动生成的测试向项目添加一个基本测试类。所有自动生成的测试都将扩展此基本类,并且它应该包含运行它们所需的所有设置信息(例如RestAssuredMockMvc控制器设置或消息测试设置)。

下面的示例来自pom.xml,展示了如何指定基本测试类

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-contract-maven-plugin</artifactId>
            <version>${spring-cloud-contract.version}</version>
            <extensions>true</extensions>
            <configuration>
                <baseClassForTests>com.example.contractTest.BaseTestClass</baseClassForTests> 
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

信息:baseClassForTests 元素允许您指定您的基本测试类。它必须是spring-cloud-contract-maven-plugin中configuration元素的一个子元素。

一旦实现和测试基类到位,测试将通过,并且应用程序和存根artifact都将被构建并安装到本地Maven仓库中。您现在可以合并更改,并且可以将应用程序和存根artifact发布到在线仓库中。

[[on-the-consumer-side]] = 在消费者侧

您可以在集成测试中使用 Spring Cloud Contract Stub Runner 来获取一个正在运行的 WireMock 实例或消息路由,以模拟实际服务。

为此,请添加对 Spring Cloud Contract Stub Runner 的依赖,示例如下

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
    <scope>test</scope>
</dependency>

您可以通过以下两种方式将生产者端的存根安装到您的 Maven 仓库中

通过检出生产者端仓库,添加契约并运行以下命令生成存根

$ cd local-http-server-repo
$ ./mvnw clean install -DskipTests

这些测试被跳过,因为生产者端的契约实现尚未到位,因此自动生成的契约测试会失败。

通过从远程仓库获取已有的生产者服务存根。为此,请将存根artifact ID和artifact仓库URL作为Spring Cloud Contract Stub Runner属性传递,示例如下

    spring.cloud.contract.stubrunner:
      ids: 'com.example:http-server-dsl:+:stubs:8080'
      repositoryRoot: https://repo.spring.io/libs-snapshot

现在你可以用@AutoConfigureStubRunner注解你的测试类。在注解中,提供group-id和artifact-id值,让Spring Cloud Contract Stub Runner为你运行协作方的存根,示例如下

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.NONE)
@AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:6565"},
        stubsMode = StubRunnerProperties.StubsMode.LOCAL)
public class LoanApplicationServiceTests {

从在线仓库下载存根时使用REMOTE存根模式,离线工作时使用LOCAL模式。

现在,在您的集成测试中,您可以接收由协作服务预期发出的HTTP响应或消息的存根版本。

Spring Initializr

快速启动您的项目

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有