AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當(dāng)前位置:首頁 > 科技  > 軟件

探秘Spring Contract:如何保障您的API符合預(yù)期?

來源: 責(zé)編: 時(shí)間:2024-03-22 17:42:29 216觀看
導(dǎo)讀微服務(wù)集成測試之痛環(huán)境搭建成本高,需啟動(dòng)多個(gè)服務(wù)用例編寫難運(yùn)行慢發(fā)現(xiàn)問題晚測試脆弱,外部依賴多1.什么是契約測試契約測試(Contract testing)是一種測試技術(shù),它通過以隔離檢查集成點(diǎn)上的每個(gè)應(yīng)用的方式,確保應(yīng)用發(fā)送或接

8a428資訊網(wǎng)——每日最新資訊28at.com

微服務(wù)集成測試之痛

  • 環(huán)境搭建成本高,需啟動(dòng)多個(gè)服務(wù)
  • 用例編寫難
  • 運(yùn)行慢
  • 發(fā)現(xiàn)問題晚
  • 測試脆弱,外部依賴多

1.什么是契約測試

契約測試(Contract testing)是一種測試技術(shù),它通過以隔離檢查集成點(diǎn)上的每個(gè)應(yīng)用的方式,確保應(yīng)用發(fā)送或接收的消息符合調(diào)用雙方共識(shí),并允許隨著時(shí)間的推移進(jìn)行演化。8a428資訊網(wǎng)——每日最新資訊28at.com

契約測試是對(duì)單元測試的增強(qiáng),針對(duì)服務(wù)接口provider測試,覆蓋了一部分本來需要集成測試才能測試到的場景。8a428資訊網(wǎng)——每日最新資訊28at.com

2.為什么要做契約測試

契約測試主要解決在存在溝通邊界情況下,測試替身(Test Double)與生產(chǎn)代碼表現(xiàn)可能不一致的問題。在契約測試中,契約由代碼生成,保持與現(xiàn)實(shí)同步,而且應(yīng)用可以獨(dú)立于其它應(yīng)用而僅基于契約進(jìn)行快速測試。8a428資訊網(wǎng)——每日最新資訊28at.com

由于集成測試容易受到網(wǎng)絡(luò)緩慢或不可靠,以及服務(wù)不可靠等因素的影響而運(yùn)行緩慢或失敗,所以通常會(huì)引入測試替身來代替真實(shí)外部服務(wù),以快速完成覆蓋度更廣的測試,讓測試真正起到作用。8a428資訊網(wǎng)——每日最新資訊28at.com

3.契約測試的定位

金字塔模型是構(gòu)建健康、快速、可維護(hù)測試集的成熟理論。8a428資訊網(wǎng)——每日最新資訊28at.com


8a428資訊網(wǎng)——每日最新資訊28at.com

8a428資訊網(wǎng)——每日最新資訊28at.com


8a428資訊網(wǎng)——每日最新資訊28at.com

4.契約測試的價(jià)值

眾所周知,越是在項(xiàng)目生命周期的后期發(fā)現(xiàn)Bug,其修復(fù)的成本就越高。8a428資訊網(wǎng)——每日最新資訊28at.com


8a428資訊網(wǎng)——每日最新資訊28at.com

8a428資訊網(wǎng)——每日最新資訊28at.com


8a428資訊網(wǎng)——每日最新資訊28at.com

不同于端到端(E2E)測試,契約測試可以在開發(fā)人員推送代碼之前運(yùn)行,在開發(fā)階段提早發(fā)現(xiàn)問題。8a428資訊網(wǎng)——每日最新資訊28at.com

契約測試還有很多端到端測試不具備的好處:8a428資訊網(wǎng)——每日最新資訊28at.com

  • 不需要調(diào)用其它組件,運(yùn)行得很快。
  • 編寫測試不需要了解系統(tǒng)全貌,更容易維護(hù)。
  • 問題只存在于被測試組件中,更容易調(diào)試和修復(fù)。
  • 極易反復(fù)運(yùn)行。
  • 每個(gè)組件獨(dú)立測試,不會(huì)引發(fā)流水線構(gòu)建時(shí)間大幅增長。

引入契約測試,還會(huì)帶來如下福利:8a428資訊網(wǎng)——每日最新資訊28at.com

  • 在提供者API就緒之前就可以開發(fā)消費(fèi)者應(yīng)用。
  • 為提供者供應(yīng)準(zhǔn)確的需求
  • 會(huì)收獲一組文檔化良好的用例,它們確切地顯示了如何使用提供者。
  • 提供者對(duì)API變更更有信息,可以準(zhǔn)確知道使用者感興趣的字段,方便地移除未使用的字段,以及添加新的字段。
  • 對(duì)提供者API進(jìn)行修改,可以立即看到會(huì)影響哪些使用者。

沒有兩個(gè)團(tuán)隊(duì)是完全一樣的,契約測試也不是萬能的,關(guān)鍵要看契約測試可以為團(tuán)隊(duì)和項(xiàng)目帶來什么。8a428資訊網(wǎng)——每日最新資訊28at.com

5.契約測試適合的場景

契約測試可以用于任何需要通信的兩個(gè)服務(wù),比如Web前端與后端API服務(wù)。8a428資訊網(wǎng)——每日最新資訊28at.com

在微服務(wù)架構(gòu)體系中,因?yàn)榇嬖诟鄨F(tuán)隊(duì)獨(dú)立、服務(wù)間調(diào)用及服務(wù)單獨(dú)演進(jìn)的情形,契約測試有了更好更大的用武之地。良好的契約測試,使得開發(fā)人員很容易避免版本地獄,是微服務(wù)開發(fā)和部署的利器。8a428資訊網(wǎng)——每日最新資訊28at.com

6.概念術(shù)語

契約測試主要涉及如下概念術(shù)語:8a428資訊網(wǎng)——每日最新資訊28at.com

  • 消費(fèi)者(Consumer):對(duì)于調(diào)用,發(fā)起請(qǐng)求的一方。對(duì)于MQ,為接收消息的一方。
  • 提供者(Provider):對(duì)于調(diào)用,響應(yīng)請(qǐng)求的一方。對(duì)于MQ,為生成消息的一方。
  • 契約(Contract):消費(fèi)者和提供者之間的共識(shí),是一系列交互的集合。對(duì)于HTTP調(diào)用,包括描述消費(fèi)者向提供者發(fā)送什么的預(yù)期請(qǐng)求,以及描述消費(fèi)者希望提供者返回的最小期望響應(yīng)。對(duì)于消息交互,則描述消費(fèi)者希望得到的最小期望消息。


8a428資訊網(wǎng)——每日最新資訊28at.com

8a428資訊網(wǎng)——每日最新資訊28at.com

7.契約測試模式

契約測試分為消費(fèi)者驅(qū)動(dòng)(consumer-driven)和提供者驅(qū)動(dòng)(Provider-driven)兩種模式。8a428資訊網(wǎng)——每日最新資訊28at.com

消費(fèi)者驅(qū)動(dòng)更具哲學(xué)意義,將API的消費(fèi)者置于設(shè)計(jì)過程的核心,來倡導(dǎo)更好的內(nèi)部微服務(wù)設(shè)計(jì)。該模式的優(yōu)點(diǎn)在于,只有消費(fèi)者正在使用的部分會(huì)得到測試,而提供者可以自由地更改消費(fèi)者不使用的任何其它部分,而不必破壞任何現(xiàn)有測試。8a428資訊網(wǎng)——每日最新資訊28at.com

提供者驅(qū)動(dòng)思路較為常規(guī),更適合開放數(shù)據(jù)或系統(tǒng)的場景。8a428資訊網(wǎng)——每日最新資訊28at.com

無論采用哪種風(fēng)格,關(guān)鍵在于獲得契約測試的好處,實(shí)現(xiàn)引入契約測試的目的。8a428資訊網(wǎng)——每日最新資訊28at.com

(1)消費(fèi)者驅(qū)動(dòng)

消費(fèi)者驅(qū)動(dòng)的契約測試運(yùn)行步驟如下:8a428資訊網(wǎng)——每日最新資訊28at.com

  • 步驟1:消費(fèi)者端
  • 編寫并運(yùn)行單元測試(包括對(duì)接口的請(qǐng)求參數(shù)和預(yù)期響應(yīng))
  • MockService代替實(shí)際服務(wù)提供者(自動(dòng))
  • 生成契約文件(自動(dòng))
  • 步驟2:提供者端
  • 啟動(dòng)服務(wù)提供者
  • 重放契約文件中的請(qǐng)求,驗(yàn)證真實(shí)響應(yīng)是否滿足預(yù)期(自動(dòng))


8a428資訊網(wǎng)——每日最新資訊28at.com

8a428資訊網(wǎng)——每日最新資訊28at.com

(2)提供者驅(qū)動(dòng)

提供者驅(qū)動(dòng)模式由提供者定義契約并驅(qū)動(dòng)整個(gè)過程。8a428資訊網(wǎng)——每日最新資訊28at.com

8a428資訊網(wǎng)——每日最新資訊28at.com

8.契約測試工具

流行的契約測試工具為:8a428資訊網(wǎng)——每日最新資訊28at.com

  • Pact:是一個(gè)命令行工具,反饋時(shí)間更短,有助于消費(fèi)者和生產(chǎn)者之間更好地溝通,支持與Maven/Gradle等集成。
  • Spring Cloud Contract:主要用于JVM環(huán)境,也容易擴(kuò)展到非JVM環(huán)境,主要適用于生產(chǎn)者驅(qū)動(dòng)的契約測試。

9.利用Pact進(jìn)行消費(fèi)者驅(qū)動(dòng)的測試價(jià)值8a428資訊網(wǎng)——每日最新資訊28at.com

利用Pact進(jìn)行契約測試的整個(gè)流程示意如下,使用了 pact 之后,依然是每個(gè)服務(wù)獨(dú)立的進(jìn)行單元測試,但是可以模擬出真實(shí)集成場景。8a428資訊網(wǎng)——每日最新資訊28at.com

  • 將一個(gè)笨重的集成測試化為兩個(gè)容易編寫、容易運(yùn)行的單元測試/接口測試
  • 解耦消費(fèi)者與提供者,甚至可以在沒有提供者實(shí)現(xiàn)的情況下開展消費(fèi)者端測試
  • 通過測試保證契約和實(shí)現(xiàn)的一致性,測試通過之時(shí)就是代碼實(shí)現(xiàn)完成之時(shí)
  • 測試前移:在開發(fā)階段就應(yīng)該運(yùn)行,并作為CI的一部分,便于盡早發(fā)現(xiàn)問題


8a428資訊網(wǎng)——每日最新資訊28at.com

8a428資訊網(wǎng)——每日最新資訊28at.com

10.Pact示例

pact契約測試分為兩步:8a428資訊網(wǎng)——每日最新資訊28at.com

  • 編寫test用例,生成契約文件(不需要啟動(dòng)服務(wù))。
  • 利用pact-verifier命令和契約文件,驗(yàn)證接口提供者是否正確 (需要啟動(dòng)提供者服務(wù))

以下為nlp-pact-parent示例:8a428資訊網(wǎng)——每日最新資訊28at.com

(1)父項(xiàng)目pom包相關(guān)

<dependencies><!-- contract testing --><dependency>    <groupId>au.com.dius</groupId>    <artifactId>pact-jvm-consumer-junit5</artifactId>    <version>4.0.10</version>    <scope>test</scope></dependency><dependency>    <groupId>au.com.dius</groupId>    <artifactId>pact-jvm-provider-junit5</artifactId>    <version>4.0.10</version>    <scope>test</scope></dependency>

(2)nlp-pact-consumer消費(fèi)端項(xiàng)目

編寫ConsumerTest生成契約:8a428資訊網(wǎng)——每日最新資訊28at.com

@ExtendWith(PactConsumerTestExt.class)@SpringBootTest(classes = PactConsumerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)@PactTestFor(providerName = "nlp-pact-provider", port = "8202")public class ConsumerTest {   private TestRestTemplate restTemplate = new TestRestTemplate();   @Test   @PactTestFor(pactMethod = "greetingPact")    void greeting_shouldReturnMessage() {      // Arrange      HttpHeaders headers = new HttpHeaders();      headers.add("Content-Type", "application/json");      // Act      ResponseEntity<Map> response = restTemplate.getForEntity("http://localhost:8202/greeting?name=John", Map.class);      // Assert      assertEquals(HttpStatus.OK, response.getStatusCode());      assertEquals(Collections.singletonMap("message", "Hello, John!"), response.getBody());   }   // Pact 定義   @Pact(consumer = "nlp-pact-consumer", provider = "nlp-pact-provider")   public RequestResponsePact greetingPact(PactDslWithProvider builder) {      return builder            .given("a request for greeting with name 'John'")            .uponReceiving("a request to greet John")            .path("/greeting")            .method("GET")            .query("name=John")            .willRespondWith()            .status(200)            .headers(Collections.singletonMap("Content-Type", "application/json"))            .body("{/"message/": /"Hello, John!/"}")            .toPact();   }}

(3)執(zhí)行ConsumerTest測試用例,生成如下契約文件:

# nlp-pact-consumer-nlp-pact-provider.json{  "provider": {    "name": "nlp-pact-provider"  },  "consumer": {    "name": "nlp-pact-consumer"  },  "interactions": [    {      "description": "a request to greet John",      "request": {        "method": "GET",        "path": "/greeting",        "query": {          "name": [            "John"          ]        }      },      "response": {        "status": 200,        "headers": {          "Content-Type": "application/json"        },        "body": {          "message": "Hello, John!"        }      },      "providerStates": [        {          "name": "a request for greeting with name 'John'"        }      ]    }  ],  "metadata": {    "pactSpecification": {      "version": "3.0.0"    },    "pact-jvm": {      "version": "4.0.10"    }  }}

(4)nlp-pact-provider提供端驗(yàn)證契約

build配置如下:8a428資訊網(wǎng)——每日最新資訊28at.com

<plugin>    <groupId>au.com.dius</groupId>    <artifactId>pact-jvm-provider-maven</artifactId>    <version>4.0.0</version>    <configuration>        <serviceProviders>            <!-- You can define as many as you need, but each must have a unique name -->            <serviceProvider>                <name>nlp-pact-provider</name>                <!-- All the provider properties are optional, and have sensible defaults (shown below) -->                <protocol>http</protocol>                <host>localhost</host>                <port>8200</port>                <path>/</path>                <pactFileDirectory>resources/pacts</pactFileDirectory>            </serviceProvider>        </serviceProviders>        <pactBrokerUrl/>    </configuration></plugin>

(5)運(yùn)行命令:mvn pact:verify,驗(yàn)證契約

Found 1 pact filesVerifying a pact between nlp-pact-consumer and nlp-pact-provider  [Using File D:/IdeaProjects/nlp-other-project-dev/nlp-pact-parent/nlp-pact-provider/target/pacts/nlp-pact-consumer-nlp-pact-provider.json]  Given a request for greeting with name 'John'         WARNING: State Change ignored as there is no stateChange URL  a request to greet John    returns a response which      has status code 200 (OK)      has a matching body (OK)[WARNING] Skipping publishing of verification results as it has been disabled (pact.verifier.publishResults is not 'true')[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  1.589 s[INFO] Finished at: 2023-03-08T15:02:33+08:00[INFO] --------

11.Pact Broker

Pact Broker是一個(gè)用于共享消費(fèi)者驅(qū)動(dòng)的合同和驗(yàn)證結(jié)果的應(yīng)用程序。8a428資訊網(wǎng)——每日最新資訊28at.com

pact主頁面:8a428資訊網(wǎng)——每日最新資訊28at.com

8a428資訊網(wǎng)——每日最新資訊28at.com

查看服務(wù)間關(guān)系:8a428資訊網(wǎng)——每日最新資訊28at.com

8a428資訊網(wǎng)——每日最新資訊28at.com

與CICD集成:8a428資訊網(wǎng)——每日最新資訊28at.com

8a428資訊網(wǎng)——每日最新資訊28at.com

12.總結(jié)

我在不少項(xiàng)目中都嘗試過實(shí)施契約測試,但是真正實(shí)施成功的并不多,主要原因還是規(guī)模和痛點(diǎn)不夠大,從而導(dǎo)致團(tuán)隊(duì)覺得沒有必要做,或者覺得做了收益比投入少。而成功的一般的都是團(tuán)隊(duì)人員足夠痛,或者經(jīng)歷過大型多團(tuán)隊(duì)項(xiàng)目中服務(wù)改變等各種痛點(diǎn),從而導(dǎo)致他們解決自己的痛點(diǎn)而主動(dòng)實(shí)施契約測試,但是前提是他們都知道契約測試。所以要成功實(shí)施契約都是有兩個(gè)主要的前提條件:1,團(tuán)隊(duì)對(duì)于相關(guān)問題足夠痛,2,團(tuán)隊(duì)懂契約測試。在這種情況下,團(tuán)隊(duì)才可能愿意主動(dòng)實(shí)施契約測試,才能成功的實(shí)施契約測試。所以首先是要讓開發(fā)團(tuán)隊(duì)懂契約測試,比如契約測試能解決什么問題,實(shí)施流程,相關(guān)測試框架等,然后等待團(tuán)隊(duì)無法忍受相關(guān)痛點(diǎn)后,成功的實(shí)施契約測試就可以水到渠成了。8a428資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-78655-0.html探秘Spring Contract:如何保障您的API符合預(yù)期?

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 使用 Node.js 和 htmx 構(gòu)建全棧 CRUD 應(yīng)用程序

下一篇: 一份關(guān)于2024年React初學(xué)者入門路線指南

標(biāo)簽:
  • 熱門焦點(diǎn)
Top