具有外部存储库中的合同的消费者驱动型合同

在这个流程中,我们执行 Consumer Driven Contract 测试。合同定义包括 存储在单独的存储库中。spring-doc.cn

先决条件

要将消费者驱动的合同与外部存储库中保存的合同一起使用,您需要设置一个 git 存储库,该存储库:spring-doc.cn

  • 包含每个生产者的所有合同定义。spring-doc.cn

  • 可以将 Contract 定义打包到 JAR 中。spring-doc.cn

  • 对于每个合同创建者,包含一种安装存根的方法(例如) 通过 Spring Cloud Contract Plugin(SCC 插件)在本地进行。pom.xmlspring-doc.cn

有关更多信息,请参阅“操作方法”部分。 其中描述了如何设置这样的存储库。 有关此类项目的示例,请参阅此示例spring-doc.cn

您还需要设置了 Spring Cloud Contract Stub Runner 的使用者代码。 有关此类项目的示例,请参阅此示例。 您还需要设置了 Spring Cloud Contract 的生产者代码以及插件。 有关此类项目的示例,请参阅此示例。 存根存储是 Nexus 或 Artifactory。spring-doc.cn

概括地说,流程如下:spring-doc.cn

  1. 使用者使用来自单独存储库的 Contract 定义。spring-doc.cn

  2. 一旦消费者的工作完成,就会在消费者上创建一个带有工作代码的分支 side 中,并向包含合同定义的单独存储库发出拉取请求。spring-doc.cn

  3. 创建者通过 Contract 接管对单独存储库的拉取请求 定义并在本地安装包含所有 Contract 的 JAR。spring-doc.cn

  4. 创建者从本地存储的 JAR 生成测试,并写入缺失的 implementation 使测试通过。spring-doc.cn

  5. 创建者的工作完成后,对包含该 Contract definitions 被合并。spring-doc.cn

  6. 在 CI 工具使用合约定义构建存储库并使用 JAR 合约定义上传到 Nexus 或 Artifactory,生产者可以合并其分支。spring-doc.cn

  7. 最后,消费者可以切换到在线工作,从 remote 位置,并且该分支可以合并到 master 中。spring-doc.cn

消费者流程

消费者:spring-doc.cn

  1. 编写一个测试,该测试将向创建者发送请求。spring-doc.cn

    由于没有服务器存在,测试失败。spring-doc.cn

  2. 克隆包含合同定义的存储库。spring-doc.cn

  3. 将需求设置为文件夹下的合同,并将使用者名称作为生产者的子文件夹。spring-doc.cn

    例如,对于名为 的 producer 和 名为 的 Consumer ,Contract 将存储在producerconsumersrc/main/resources/contracts/producer/consumer/)spring-doc.cn

  4. 定义 Contract 后,将 producer 存根安装到本地存储,如下例所示:spring-doc.cn

    $ cd src/main/resource/contracts/producer
    $ ./mvnw clean install
  5. 在使用者测试中设置 Spring Cloud Contract (SCC) Stub Runner,以:spring-doc.cn

    • 从本地存储获取生产者存根。spring-doc.cn

    • 在 stubs-per-consumer 模式下工作(这将启用消费者驱动的 Contract 模式)。spring-doc.cn

      SCC 存根运行程序:spring-doc.cn

    • 获取生产者存根。spring-doc.cn

    • 使用创建器存根运行内存中 HTTP 服务器存根。 现在,您的测试与 HTTP 服务器存根通信,并且您的测试通过。spring-doc.cn

    • 使用合同定义创建者的新合同创建对存储库的拉取请求。spring-doc.cn

    • 对使用者代码进行分支,直到生成者团队合并其代码。spring-doc.cn

下面的 UML 图显示了使用者流:spring-doc.cn

流概览消费者 cdc-外部消费者

生产者流

制片人:spring-doc.cn

  1. 使用合同定义接管对存储库的拉取请求。你可以的 从命令行,如下所示spring-doc.cn

    $ git checkout -b the_branch_with_pull_request master
    git pull https://github.com/user_id/project_name.git the_branch_with_pull_request
  2. 安装合同定义,如下所示spring-doc.cn

    $ ./mvnw clean install
  3. 将插件设置为从 JAR 而不是 from 获取 Contract 定义,如下所示:src/test/resources/contractsspring-doc.cn

    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
    }
  4. 运行生成以生成测试和存根,如下所示:spring-doc.cn

    Maven 系列
    ./mvnw clean install
    Gradle
    ./gradlew clean build
  5. 写入缺少的实现,以使测试通过。spring-doc.cn

  6. 将拉取请求合并到带有合同定义的存储库,如下所示:spring-doc.cn

    $ 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。spring-doc.cn

  7. 切换到远程工作。spring-doc.cn

  8. 设置插件,以便不再从本地获取 Contract 定义 存储,但从远程位置存储,如下所示:spring-doc.cn

    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
    }
  9. 将创建者代码与新实现合并。spring-doc.cn

  10. CI 系统:spring-doc.cn

下面的 UML 图显示了生产者进程:spring-doc.cn

流概览消费者 cdc-外部生产者