契約測試和CDC Testing框架:Spring Cloud Contract

關鍵詞:

  • Spring Cloud Contract:一個CDC Testing框架,類似的還有Pact
  • CDC:Consumer Driven Contract Testing
  • Provider:服務提供方
  • Consumer:服務調(diào)用方

什么是契約測試

微服務系統(tǒng)由大量的微服務節(jié)點組成,對其中一個服務節(jié)點做測試,需要部署依賴的服務節(jié)點,實際應用中會有以下的問題:

  • 依賴服務沒有開發(fā)完成,無法部署,導致無法測試。
  • 依賴服務不穩(wěn)定(測試環(huán)境問題、部署異常、數(shù)據(jù)問題等等),導致測試不通過。
  • 依賴的服務發(fā)生變化沒有知會到調(diào)用服務的一方,導致測試不通過。

在這次測試中,我們定義調(diào)用服務或者說消費服務的一方為Consumer,而依賴的服務提供方為Provider

針對以上問題,CDC主要定義了以下特性:

  • Consumer根據(jù)自己的對Provider的期望編寫Contract
  • Provider根據(jù)Contract實現(xiàn)接口并進行測試(CDC框架可以根據(jù)Contract自動生成測試代碼用于驗證Provider提供的服務是否和Contract一致)
  • Provider根據(jù)Contract生成Stubs實現(xiàn)對Provider進行Mock。

Sping Cloud Contract代碼實例

一、通過契約驗證Provider的服務和Contract是否一致

Provider引入依賴

引入依賴到/src/test目錄所在模塊的pom.xml中

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-contract-verifier</artifactId>
    <version>2.2.4.RELEASE</version>
    <scope>test</scope>
</dependency>

實際如下圖


引入plugin到/src/test目錄所在模塊的pom.xml中

<plugin>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    <version>2.2.4.RELEASE</version>
    <extensions>true</extensions>
    <configuration>
        <baseClassForTests>com.alibaba.cxdc.qxc.sweetnurse.BaseMock</baseClassForTests>
    </configuration>
</plugin>

如下圖:


Provider端編寫契約

契約可以使用groovy(推薦)或者YAML編寫,我的契約文件存放路徑為src/test/resources/contracts

契約對應的provider接口為:


Provider端根據(jù)Contract自動生成Test Class

執(zhí)行命令:mvn clean install


生成的stubs.jar會自動安裝到本地Maven倉庫(.m2/repository):

執(zhí)行生成的Test驗證Provider提供的服務和Contract定義是否一致

執(zhí)行命令:mvn clean install或者mvn test時,會根據(jù)契約驗證provider提供的服務是否和契約描述的一致:

1.契約描述返回值為xxx,實際接口返回為ceshi,所以test執(zhí)行不通過:


測試不通過,provider提供的服務和契約描述不一致

2.修改契約文件如下:


3.驗證通過:


測試通過,provider提供的服務和契約描述一致

后續(xù)如果Provider接口發(fā)生了變化,測試會驗證不通過。

二、Consumer基于stubs進行mock測試

安裝stubs.jar到本地Maven倉庫

Provider的目錄下執(zhí)行命令mvn clean install會自動安裝stub包到本地Maven倉庫

本文中stubs.jar的Maven坐標如下:

  • groupId:com.alibaba.cxdc.qxc
  • artifactId:sweetnurse-start
  • version:1.0.0
  • classfier:stubs

Consumer端引入依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
    <version>3.0.0</version>
    <scope>test</scope>
</dependency>

編寫Consumer的測試類

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureStubRunner(stubsMode = StubRunnerProperties.StubsMode.LOCAL,
    ids = "com.alibaba.cxdc.qxc:sweetnurse-start:1.0.0:stubs:10001")
public class StubTest {
    private String url = "http://localhost:10001";

    @Test
    public void testMethod() throws Exception {
        RestTemplate restTemplate = new RestTemplate();
        JSONObject param = new JSONObject();
        param.put("contract", "ceshi");

        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<JSONObject> entity = new HttpEntity<>(param,requestHeaders);

        ResponseEntity<String> result = restTemplate.postForEntity(url + "/rest/workshift/sayHello", entity,
            String.class);

        System.out.println(result.getStatusCode());
    }
}

實際代碼如圖:



執(zhí)行結(jié)果如圖:


Consumer test執(zhí)行通過

AutoConfigureStubRunner注解及內(nèi)部屬性的含義:
1.@AutoConfigureStubRunner:根據(jù)ids屬性獲取stubs.jar并啟動web服務器供測試mock調(diào)用

2.ids的含義
ids = "com.alibaba.cxdc.qxc:sweetnurse-start:1.0.0:stubs:10001
ids = "groupId:artifactId:version:classfier:port"
其中version如果用+表示取最新版本

3.stubsMode的含義:
StubRunnerProperties.StubsMode.LOCAL:從本地的maven倉庫獲取stubs.jar
StubRunnerProperties.StubsMode.REMOTE:從遠程maven倉庫獲取stubs.jar
StubRunnerProperties.StubsMode.CLASSPATH:默認值、從本地java classpath獲取stubs.jar

參考文檔:
Spring Cloud Contract Referenct
Pact

What's Next?
1.Pact框架和Spring Cloud Contract區(qū)別,針對不同語言的適用性是否更好。
2.怎么在現(xiàn)有自動化測試平臺中實現(xiàn)或者集成契約測試能力。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 什么是契約測試 測試是軟件流程中非常重要,不可或缺的一個環(huán)節(jié)。一般的測試分為單元測試,集成測試,端到端的手工測試,...
    RaiseHead閱讀 4,305評論 0 13
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,641評論 19 139
  • Spring Cloud Contract是契約測試的一個實現(xiàn),最早看到契約測試還是在《微服務設計》書中,不過那時...
    MrTT閱讀 3,646評論 3 2
  • 什么是契約 如果從契約產(chǎn)生的階段來說,現(xiàn)有資料表明最早要追溯到西周時期的《周恭王三年裘衛(wèi)典田契》,將契約文字刻寫在...
    ThoughtWorks閱讀 3,255評論 1 12
  • 漸變的面目拼圖要我怎么拼? 我是疲乏了還是投降了? 不是不允許自己墜落, 我沒有滴水不進的保護膜。 就是害怕變得面...
    悶熱當乘涼閱讀 4,489評論 0 13

友情鏈接更多精彩內(nèi)容