Spring Cloud ContractSpring Cloud Contract4.2.1

Spring Cloud Contract 是一个伞形项目,包含帮助用户成功实施消费者驱动合同 (Consumer Driven Contracts) 方法的解决方案。目前 Spring Cloud Contract 包含 Spring Cloud Contract Verifier 项目。

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

  • 默认情况下,生成用于 WireMock (HTTP 服务器桩) 的 JSON 桩定义,以便在对客户端代码进行集成测试(客户端测试)时使用。测试代码仍需手动编写,但测试数据由 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 如何支持其他语言,请查看 这篇博客文章

特性

在测试与其它服务通信的应用时,我们可以选择以下两种方法之一:

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

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

这两种方法各有优缺点。让我们先关注第一种。部署所有微服务并执行端到端测试

优点

  • 模拟生产环境

  • 测试服务间的真实通信

缺点

  • 为了测试一个微服务,我们可能需要部署 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 中配置元素的子元素。

实现和测试基础类就绪后,测试将通过,并且应用程序和桩 artifacts 都将在本地 Maven 仓库中构建和安装。您现在可以合并更改,并可以在在线仓库中发布应用程序和桩 artifacts。

[[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 的属性传递,如下例所示

    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 社区所有即将到来的活动。

查看全部