消費者驅動合約,合約位於外部儲存庫中
在此流程中,我們執行消費者驅動合約測試。合約定義儲存在個別的儲存庫中。
先決條件
若要使用消費者驅動合約,並將合約保存在外部儲存庫中,您需要設定一個 Git 儲存庫,其
-
包含每個生產者的所有合約定義。
-
可以將合約定義打包在 JAR 中。
-
對於每個合約生產者,都包含一種方式 (例如,
pom.xml
) 以透過 Spring Cloud Contract 外掛程式 (SCC 外掛程式) 在本地安裝 Stub。
您還需要設定了 Spring Cloud Contract Stub Runner 的消費者程式碼。如需此類專案的範例,請參閱此範例。您還需要設定了 Spring Cloud Contract 的生產者程式碼,以及一個外掛程式。如需此類專案的範例,請參閱此範例。Stub 儲存空間為 Nexus 或 Artifactory。
在高階層次,流程如下
-
消費者使用來自個別儲存庫的合約定義。
-
一旦消費者完成工作,就會在消費者端建立一個包含工作程式碼的分支,並向保存合約定義的個別儲存庫發出提取請求。
-
生產者接管對包含合約定義的個別儲存庫的提取請求,並在本地安裝包含所有合約的 JAR。
-
生產者從本地儲存的 JAR 產生測試,並編寫缺少的實作以使測試通過。
-
一旦生產者完成工作,對保存合約定義的儲存庫的提取請求就會合併。
-
在 CI 工具建置包含合約定義的儲存庫,並且包含合約定義的 JAR 上傳到 Nexus 或 Artifactory 之後,生產者可以合併其分支。
-
最後,消費者可以切換到線上工作,從遠端位置提取生產者的 Stub,並且分支可以合併到 master。
消費者流程
消費者
-
編寫一個會向生產者發送請求的測試。
由於沒有伺服器,測試失敗。
-
複製保存合約定義的儲存庫。
-
將需求設定為資料夾下的合約,並以消費者名稱作為生產者的子資料夾。
例如,對於名為
producer
的生產者和名為consumer
的消費者,合約將儲存在src/main/resources/contracts/producer/consumer/
下) -
一旦定義了合約,就將生產者 Stub 安裝到本地儲存空間,如下列範例所示
$ cd src/main/resource/contracts/producer $ ./mvnw clean install
-
在消費者測試中設定 Spring Cloud Contract (SCC) Stub Runner,以
-
從本地儲存空間提取生產者 Stub。
-
在每個消費者的 Stub 模式下工作 (這會啟用消費者驅動合約模式)。
SCC Stub Runner
-
提取生產者 Stub。
-
使用生產者 Stub 執行記憶體內 HTTP 伺服器 Stub。現在您的測試會與 HTTP 伺服器 Stub 通訊,並且您的測試通過。
-
建立對包含合約定義的儲存庫的提取請求,其中包含生產者的新合約。
-
分支您的消費者程式碼,直到生產者團隊合併他們的程式碼。
-
以下 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 而不是從
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 }
===
-
執行建置以產生測試和 Stub,如下所示
=== 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 系統建置包含合約定義的專案,並將包含合約定義的 JAR 上傳到 Nexus 或 Artifactory。
-
切換到遠端工作。
-
設定外掛程式,以便不再從本地儲存空間而是從遠端位置取得合約定義,如下所示
=== 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 系統
-
建置專案。
-
產生測試、Stub 和 Stub JAR。
-
將包含應用程式和 Stub 的成品上傳到 Nexus 或 Artifactory。
-
以下 UML 圖表顯示了生產者流程
