javascript
消费者驱动的微服务契约测试套件Spring Cloud Contract
在微服務架構下,你的服務可能由不同的團隊提供和維護,在這種情況下,接口的開發和維護可能會帶來一些問題,比如服務端調整架構或接口調整而對消費者不透明,導致接口調用失敗。
為解決這些問題,Ian Robinson提出了一個以服務消費者定義契約為驅動的開發模式:“Consumer-Driver Contracts(CDC)”,就是:消費者驅動契約。
通常我們開發中主要由服務提供方約定接口,雖然提供方架構調整或改變接口之前通常會通知消費者,但可能還存在上述風險,如果上線出現問題就GG了,而CDC則是以消費者提出接口契約,交由服務提供方實現,并以測試用例對契約進行產生約束,所以服務提供方在滿足測試用例的情況下可以自行更改接口或架構實現而不影響消費者。
消費者驅動的契約測試(Consumer-Driven Contracts,簡稱CDC),是指從消費者業務實現的角度出發,驅動出契約,再基于契約,對提供者驗證的一種測試方式。
如果你目前使用SpringCloud作為微服務基礎環境,那么集成SpringCloud Contracts也是比較好的選擇。
原本你要測試的話必須啟動相應的服務。像下面這樣:
使用了Spring Cloud Contract之后,你就不需要啟動這么多的服務了。像下面這樣:
也許你發現了,出現了一個新的生物,叫STUB。這是個什么東西呢?稍后會詳細說,這里你先就認為它可以模擬出provider,然后消費者直接調用就可以模擬服務調用了。
是不是不錯。
好,接下來我們透過代碼來詳細的講解下這個套件吧。
我們接下來模擬一個流程。現在有兩個團隊,分別負責不同的服務。
這里就假設有provider團隊和consumer團隊。那么當provider團隊的服務還沒有開發好,或者provider的團隊的服務沒有在啟動的時候,我們可不可以進行開發呢?
答案是可以的。
契約(Contract)
這里引入一個重要的概念,就是契約,Contract。這是什么呢?很簡單,就是provider和consumer事先要約定好一個接口的規范,之后雙方提供服務接口和消費服務接口都要按照這個契約來。
先來看看代碼的基本結構:
分別有三個模塊:common、consumer、provider。
接下來一一介紹:
Common模塊
然后分別有兩個類,一個是分頁Page實體,另外一個是Customer實體類。
1、Customer:
2、Page:
待會我們會在provider和consumer中都用到。
Provider程序
先來看看pom依賴:**
1、引入spring-cloud-starter-contract-verifier
注:引入verfier是為了驗證是否符合契約
2、引入spring-cloud-contract-maven-plugin:
baseClassForTests這個就是你要符合契約的測試代碼。
這里主要介紹和contract緊相關的依賴。其他依賴你可以到具體的源碼中查看(點擊“閱讀原文”)。
3、契約
先來看看契約的定義是什么樣。
我們在provider的test下的resources下新建了一個contracts目錄,這個就是放置契約的地方,里邊有個shouldReturnAllCustomers的groovy文件就是我們的契約,來看看吧。
shouldReturnAllCustomers.grovvy:
我們看到有三個部分:description、request、response。通過request定義了請求時的url和method,然后通過response約定返回時的headers和body信息。
契約采用groovy的DSL描述,所以一目了然,就是通過url:/ api / customers來取得一個json格式的客戶列表,返回兩個客戶信息。
契約約定好了。接下來我們就來實現這個契約吧:
CustomerRepository:
CustomerRestController:
接下來我們就來生成stub jar文件。這個jar文件的目的就是可以被消費者拿來當做一個模擬服務來啟動然后在本地跑測試用例,而不需要真正的服務提供者啟動。
4、生成stub jar:
執行install把stubjar包安裝到本地(在正式開發的時候可以deploy倉庫)
| clean install -Dmaven.test.skip=true |
發現已經安裝好了:
這時候我們可以通過contract插件簡單的看下效果:
run之后,我們會看到通過啟動stub 的jar文件,我們可以模擬一個真實的服務:
然后我們訪問:http://localhost:8080/api/customers
可以發現,我們通過契約然后生成了stub jar,然后啟動stub jar居然模擬了契約約定好的服務。
接下來我們去編寫一個consumer程序吧。
另外啟動stub也可以通過以下命令來啟動:
| java -jar spring-cloud-contract-provider-0.0.1-SNAPSHOT-stubs.jar --stubrunner.ids=com.importsource.springcloud:spring-cloud-contract-provider:+:8080 --stubrunner.workOffline=true |
Consumer
1、spring-cloud-starter-contract-stub-runner
依賴spring-cloud-starter-contract-stub-runner:
通過這個依賴,我們一會就可以啟動stub來模擬啟動一個契約好的服務了。
接下來,作為消費者端,來寫一個測試用例,來模擬測試服務吧:
2、SpringCloudContractConsumerApplicationTests:
這里使用到了以下的注解:
| (ids = {"com.importsource.springcloud:spring-cloud-contract-provider:+:8080"}, workOffline = true) |
@AutoConfigureStubRunner
通過@AutoConfigureStubRunner來自動配置注入一個StubRunner。
1、ids:
然后通過ids去定位到剛剛通過clean install好的那個stub jar 包,然后在8080端口去啟動這個stub jar。
ids的格式是長這樣:
groupId:artifactId:version:classifier:port
2、workOffline = true
是指使用本地maven庫,不要使用線上的版本,所以你只要把Consumer在你本機上安裝過就可以了。
然后運行測試:
發現測試通過了。
總結
你應該發現了,我們根本沒有真正的啟動服務提供者,而是在本地啟動了stub就模擬測試了一次服務調用。
本文首先向你介紹了消費者驅動測試的基本背景,然后我們編寫了一個服務的契約,并介紹如何定義Spring Cloud Contract的契約,然后我們借助contract maven插件生成了stub jar包,然后install到本地。接著我們編寫了消費者端的測試用例,通過stub runner來模擬服務提供者完成了一次消費者調用服務的測試。
契約測試的工具除了Spring Cloud Contract外,還有其他的一些工具可供你選擇,比如:Janus,Pact,Pacto等。
示例代碼查看:https://github.com/importsource/spring-cloud-contract
總結
以上是生活随笔為你收集整理的消费者驱动的微服务契约测试套件Spring Cloud Contract的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Cloud Hystrix
- 下一篇: 美团外卖Android平台化的复用实践