领先一步
VMware 提供培训和认证,助您加速进步。
了解更多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/消息存根(在开发客户端时使用)与实际的服务端实现行为完全一致
推广验收测试驱动开发方法和微服务架构风格
提供一种发布契约变更的方式,使其在通信双方立即可见
在服务器端生成样板测试代码
[[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响应或消息的存根版本。