此版本仍在开发中,目前尚不被视为稳定版本。如需最新稳定版本,请使用 spring-cloud-contract 5.0.2spring-doc.cadn.net.cn

消费者驱动契约,契约存放在外部仓库中

在此流程中,我们执行消费者驱动契约测试。契约定义存储在单独的仓库中。spring-doc.cadn.net.cn

前置条件

要使用消费者驱动的契约(consumer-driven contracts),并将契约存储在外部仓库中,您需要设置一个 Git 仓库,其内容如下:spring-doc.cadn.net.cn

有关更多信息,请参阅“如何操作”部分,其中我们介绍了如何设置此类存储库。有关此类项目的示例,请参阅此示例spring-doc.cadn.net.cn

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

从高层角度来看,流程如下:spring-doc.cadn.net.cn

  1. 消费者与独立仓库中的契约定义进行协作。spring-doc.cadn.net.cn

  2. 当消费者的工作完成后,会在消费者端创建一个包含工作代码的分支,并向存放契约定义的独立仓库提交拉取请求。spring-doc.cadn.net.cn

  3. 生产者接管拉取请求,将其提交到包含契约定义的独立仓库,并将包含所有契约的JAR本地安装。spring-doc.cadn.net.cn

  4. 生产者从本地存储的JAR文件中生成测试用例,并编写缺失的实现代码,以使测试通过。spring-doc.cadn.net.cn

  5. 一旦生产者的工作完成,对包含合同定义的仓库的拉取请求将被合并。spring-doc.cadn.net.cn

  6. 经过CI工具使用契约定义构建存储库后,契约定义JAR文件将被上传到Nexus或Artifactory。生产者可以合并其分支。spring-doc.cadn.net.cn

  7. 最终,消费者可以切换到在线工作,从远程位置获取生产者的存档,并将分支合并到主分支。spring-doc.cadn.net.cn

消费者流程

  1. 在生产者发送请求时,写一个测试来捕获该请求。spring-doc.cadn.net.cn

    测试失败,因为没有服务器存在。spring-doc.cadn.net.cn

  2. 克隆包含契约定义的仓库。spring-doc.cadn.net.cn

  3. 在文件夹中以合同形式设置要求,生产者的消费者名称作为生产者文件夹的子文件夹。spring-doc.cadn.net.cn

    例如,对于名为producer的生产者和名为consumer的使用者,这些合同将存储在src/main/resources/contracts/producer/consumer/)下spring-doc.cadn.net.cn

  4. 一旦定义了合同,就会将生产者存档安装到本地存储,如下例所示:spring-doc.cadn.net.cn

    $ cd src/main/resource/contracts/producer
    $ ./mvnw clean install
  5. 为使用者测试设置Spring Cloud Contract (SCC) Stub Runner,以执行以下操作:spring-doc.cadn.net.cn

下图显示了以下 UML 图中显示的消费流:spring-doc.cadn.net.cn

flow-overview-consumer-cdc-external-consumer

生产者流程

The producer:spring-doc.cadn.net.cn

  1. 接管具有合同定义的仓库的拉取请求。你可以从命令行进行,如下所示spring-doc.cadn.net.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.cadn.net.cn

    $ ./mvnw clean install
  3. 设置插件从 JAR 文件而不是从 src/test/resources/contracts 中获取合同定义,方法如下:spring-doc.cadn.net.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.cadn.net.cn

    Maven
    ./mvnw clean install
    Gradle
    ./gradlew clean build
  5. 编写缺失的实现,使测试通过。spring-doc.cadn.net.cn

  6. 合并包含协定定义的存储库中的拉取请求,如下所示:spring-doc.cadn.net.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 系统使用契约定义构建项目,然后将包含契约定义的 JAR 文件上传到 Nexus 或 Artifactory。spring-doc.cadn.net.cn

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

  8. 设置了插件,以便不再从本地存储中获取合同定义,而是从远程位置获取,如下所示:spring-doc.cadn.net.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.cadn.net.cn

  10. 系统是:spring-doc.cadn.net.cn

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

flow-overview-consumer-cdc-external-producer