使用外部倉庫中的契約進行消費者驅動契約
在此流程中,我們執行消費者驅動的契約測試。契約定義儲存在單獨的倉庫中。
先決條件
要將消費者驅動契約與外部倉庫中的契約一起使用,您需要設定一個 Git 倉庫,該倉庫需要滿足以下條件:
-
包含每個生產者的所有契約定義。
-
可以將契約定義打包成 JAR。
-
對於每個契約生產者,包含一種透過 Spring Cloud Contract 外掛(SCC 外掛)在本地安裝存根的方式(例如,
pom.xml)。
您還需要設定了 Spring Cloud Contract Stub Runner 的消費者程式碼。有關此類專案的示例,請參閱此示例。您還需要設定了 Spring Cloud Contract 和外掛的生產者程式碼。有關此類專案的示例,請參閱此示例。存根儲存是 Nexus 或 Artifactory。
在高層,流程如下:
-
消費者使用單獨倉庫中的契約定義。
-
消費者完成工作後,在消費者端建立一個包含工作程式碼的分支,並向儲存契約定義的單獨倉庫發起拉取請求。
-
生產者接管對儲存契約定義的單獨倉庫的拉取請求,並在本地安裝包含所有契約的 JAR。
-
生產者從本地儲存的 JAR 生成測試,並編寫缺失的實現以使測試透過。
-
生產者完成工作後,合併對儲存契約定義的倉庫的拉取請求。
-
CI 工具構建包含契約定義的倉庫並將包含契約定義的 JAR 上傳到 Nexus 或 Artifactory 後,生產者可以合併其分支。
-
最後,消費者可以切換到線上工作以從遠端位置獲取生產者的存根,並且可以將分支合併到主分支。
消費者流程
消費者
-
編寫一個會向生產者傳送請求的測試。
由於沒有伺服器,測試失敗。
-
克隆儲存契約定義的倉庫。
-
在資料夾下將需求設定為契約,以消費者名稱作為生產者的子資料夾。
例如,對於名為
producer的生產者和名為consumer的消費者,契約將儲存在src/main/resources/contracts/producer/consumer/之下)。 -
定義契約後,將生產者存根安裝到本地儲存,示例如下:
$ cd src/main/resource/contracts/producer $ ./mvnw clean install -
在消費者測試中設定 Spring Cloud Contract (SCC) Stub Runner,以:
-
從本地儲存獲取生產者存根。
-
在“每消費者存根”模式下工作(這會啟用消費者驅動契約模式)。
SCC Stub Runner
-
獲取生產者存根。
-
執行一個帶有生產者存根的記憶體 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 而不是從
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 masterCI 系統構建包含契約定義的專案,並將包含契約定義的 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 系統
-
構建專案。
-
生成測試、存根和存根 JAR。
-
將帶有應用程式和存根的工件上傳到 Nexus 或 Artifactory。
-
以下 UML 圖顯示了生產者流程: