具有外部存储库中的合同的消费者驱动型合同
在这个流程中,我们执行 Consumer Driven Contract 测试。合同定义包括 存储在单独的存储库中。
先决条件
要将消费者驱动的合同与外部存储库中保存的合同一起使用,您需要设置一个 git 存储库,该存储库:
-
包含每个生产者的所有合同定义。
-
可以将 Contract 定义打包到 JAR 中。
-
对于每个合同创建者,包含一种安装存根的方法(例如) 通过 Spring Cloud Contract Plugin(SCC 插件)在本地进行。
pom.xml
您还需要设置了 Spring Cloud Contract Stub Runner 的使用者代码。 有关此类项目的示例,请参阅此示例。 您还需要设置了 Spring Cloud Contract 的生产者代码以及插件。 有关此类项目的示例,请参阅此示例。 存根存储是 Nexus 或 Artifactory。
概括地说,流程如下:
-
使用者使用来自单独存储库的 Contract 定义。
-
一旦消费者的工作完成,就会在消费者上创建一个带有工作代码的分支 side 中,并向包含合同定义的单独存储库发出拉取请求。
-
创建者通过 Contract 接管对单独存储库的拉取请求 定义并在本地安装包含所有 Contract 的 JAR。
-
创建者从本地存储的 JAR 生成测试,并写入缺失的 implementation 使测试通过。
-
创建者的工作完成后,对包含该 Contract definitions 被合并。
-
在 CI 工具使用合约定义构建存储库并使用 JAR 合约定义上传到 Nexus 或 Artifactory,生产者可以合并其分支。
-
最后,消费者可以切换到在线工作,从 remote 位置,并且该分支可以合并到 master 中。
消费者流程
消费者:
-
编写一个测试,该测试将向创建者发送请求。
由于没有服务器存在,测试失败。
-
克隆包含合同定义的存储库。
-
将需求设置为文件夹下的合同,并将使用者名称作为生产者的子文件夹。
例如,对于名为 的 producer 和 名为 的 Consumer ,Contract 将存储在
producer
consumer
src/main/resources/contracts/producer/consumer/
) -
定义 Contract 后,将 producer 存根安装到本地存储,如下例所示:
$ cd src/main/resource/contracts/producer $ ./mvnw clean install
-
在使用者测试中设置 Spring Cloud Contract (SCC) Stub Runner,以:
-
从本地存储获取生产者存根。
-
在 stubs-per-consumer 模式下工作(这将启用消费者驱动的 Contract 模式)。
SCC 存根运行程序:
-
获取生产者存根。
-
使用创建器存根运行内存中 HTTP 服务器存根。 现在,您的测试与 HTTP 服务器存根通信,并且您的测试通过。
-
使用合同定义创建者的新合同创建对存储库的拉取请求。
-
对使用者代码进行分支,直到生成者团队合并其代码。
-
下面的 UML 图显示了使用者流:
生产者流
制片人:
-
使用合同定义接管对存储库的拉取请求。你可以的 从命令行,如下所示
$ git checkout -b the_branch_with_pull_request master git pull https://github.com/user_id/project_name.git the_branch_with_pull_request
-
安装合同定义,如下所示
$ ./mvnw clean install
-
将插件设置为从 JAR 而不是 from 获取 Contract 定义,如下所示:
src/test/resources/contracts
- Maven 系列
-
<plugin> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-contract-maven-plugin</artifactId> <version>${spring-cloud-contract.version}</version> <extensions>true</extensions> <configuration> <!-- We want to use the JAR with contracts with the following coordinates --> <contractDependency> <groupId>com.example</groupId> <artifactId>beer-contracts</artifactId> </contractDependency> <!-- The JAR with contracts should be taken from Maven local --> <contractsMode>LOCAL</contractsMode> <!-- ... additional configuration --> </configuration> </plugin>
- Gradle
-
contracts { // We want to use the JAR with contracts with the following coordinates // group id `com.example`, artifact id `beer-contracts`, LATEST version and NO classifier contractDependency { stringNotation = 'com.example:beer-contracts:+:' } // The JAR with contracts should be taken from Maven local contractsMode = "LOCAL" // Additional configuration }
-
运行生成以生成测试和存根,如下所示:
- Maven 系列
-
./mvnw clean install
- Gradle
-
./gradlew clean build
-
写入缺少的实现,以使测试通过。
-
将拉取请求合并到带有合同定义的存储库,如下所示:
$ git commit -am "Finished the implementation to make the contract tests pass" $ git checkout master $ git merge --no-ff the_branch_with_pull_request $ git push origin master
CI 系统使用合约定义构建项目,并使用 将合同定义设置为 Nexus 或 Artifactory。
-
切换到远程工作。
-
设置插件,以便不再从本地获取 Contract 定义 存储,但从远程位置存储,如下所示:
- Maven 系列
-
<plugin> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-contract-maven-plugin</artifactId> <version>${spring-cloud-contract.version}</version> <extensions>true</extensions> <configuration> <!-- We want to use the JAR with contracts with the following coordinates --> <contractDependency> <groupId>com.example</groupId> <artifactId>beer-contracts</artifactId> </contractDependency> <!-- The JAR with contracts should be taken from a remote location --> <contractsMode>REMOTE</contractsMode> <!-- ... additional configuration --> </configuration> </plugin>
- Gradle
-
contracts { // We want to use the JAR with contracts with the following coordinates // group id `com.example`, artifact id `beer-contracts`, LATEST version and NO classifier contractDependency { stringNotation = 'com.example:beer-contracts:+:' } // The JAR with contracts should be taken from a remote location contractsMode = "REMOTE" // Additional configuration }
-
将创建者代码与新实现合并。
-
CI 系统:
-
生成项目。
-
生成测试、存根和存根 JAR。
-
将包含应用程序和存根的工件上传到 Nexus 或 Artifactory。
-
下面的 UML 图显示了生产者进程: