偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

聊一聊契約測(cè)試

開(kāi)發(fā) 開(kāi)發(fā)工具
契約測(cè)試不是銀彈,它不是替代E2E測(cè)試的終結(jié)者,更不是單元測(cè)試的升級(jí)換代,它更偏向于服務(wù)和服務(wù)之間的API測(cè)試,通過(guò)解耦服務(wù)依賴關(guān)系和單元測(cè)試來(lái)加快測(cè)試的運(yùn)行效率。

一、什么是契約

如果從契約產(chǎn)生的階段來(lái)說(shuō),現(xiàn)有資料表明最早要追溯到西周時(shí)期的《周恭王三年裘衛(wèi)典田契》,將契約文字刻寫在器皿上,就是為了使契文中規(guī)定的內(nèi)容得到多方承認(rèn)、信守,“萬(wàn)年永寶用”。所以訂立契約的本身,就是為了要信守,就是對(duì)誠(chéng)信關(guān)系的一種確立。誠(chéng)信,是我國(guó)所固有的一種優(yōu)良傳統(tǒng),也是延續(xù)了幾千年的一種民族美德,在中國(guó)儒家的思想體系里,是倫理道德內(nèi)容中的一部分。

[[232064]]

《現(xiàn)藏于臺(tái)北故宮博物院》

現(xiàn)實(shí)真的是那么美好嗎?小時(shí)候的價(jià)值觀教育未能改變社會(huì)的現(xiàn)狀,缺少契約精神的案例卻比比皆是。

那么,契約真的要消失了嗎?不盡然,在軟件測(cè)試領(lǐng)域,我們又重新拾起了契約這把利器。

二、發(fā)展歷程

接下來(lái)讓我們回顧一下契約測(cè)試的起源和發(fā)展歷程:

假設(shè)我們有這樣一個(gè)場(chǎng)景:A團(tuán)隊(duì)負(fù)責(zé)開(kāi)發(fā)API服務(wù),B團(tuán)隊(duì)進(jìn)行API調(diào)用消費(fèi)服務(wù)。

為了保證API的正確性,我們會(huì)對(duì)外部系統(tǒng)的API進(jìn)行測(cè)試(除非你100%相信外部系統(tǒng)永遠(yuǎn)正確和保持不變),這很可能就會(huì)導(dǎo)致一個(gè)問(wèn)題,當(dāng)外部系統(tǒng)并不那么穩(wěn)定或者請(qǐng)求時(shí)間過(guò)長(zhǎng)時(shí),就會(huì)導(dǎo)致我們的測(cè)試效率很低,并且穩(wěn)定性下降。比如當(dāng)外部API掛掉導(dǎo)致測(cè)試失敗時(shí),你并不能完全確信是API功能被更而改導(dǎo)致的失敗還是運(yùn)行環(huán)境不穩(wěn)定導(dǎo)致的請(qǐng)求失敗。

最初,解決這個(gè)問(wèn)題的方案是構(gòu)建測(cè)試替身(Test Double),通過(guò)模擬外部API的響應(yīng)行為來(lái)增強(qiáng)測(cè)試的穩(wěn)定性和反應(yīng)速度。實(shí)現(xiàn)手段是在測(cè)試環(huán)境中搭建一個(gè)模擬服務(wù)環(huán)境,通過(guò)設(shè)定一些請(qǐng)求參數(shù)來(lái)返回不同的響應(yīng)內(nèi)容,然后再被內(nèi)部系統(tǒng)調(diào)用,來(lái)保證調(diào)用端的正確性。構(gòu)建模擬環(huán)境時(shí)我們可以使用幾種不同的測(cè)試手段,如Dummy,F(xiàn)ake,Stubs,Spies,Mocks等??墒?,問(wèn)題又來(lái)了,如果使用測(cè)試替身那如何能保證外部系統(tǒng)API變化時(shí)得到及時(shí)的響應(yīng),換句話說(shuō),當(dāng)內(nèi)部系統(tǒng)測(cè)試都通過(guò)的通過(guò)時(shí),如何能保證真正的外部API沒(méi)有變化?

一個(gè)比較簡(jiǎn)單的方式是部分測(cè)試使用測(cè)試替身,另外一部分測(cè)試定期調(diào)用真實(shí)的外部API,這樣既保證了測(cè)試的運(yùn)行效率、調(diào)用端的準(zhǔn)確性,又能確保當(dāng)真實(shí)外部系統(tǒng)API改變時(shí)能得到反饋。

是不是到這里就皆大歡喜了呢?

如果劇情到這里就結(jié)束的話,未免太過(guò)俗套。這個(gè)方案最大的缺陷在于API的反應(yīng)速度,真實(shí)外部API的反饋周期過(guò)長(zhǎng),如果減少真實(shí)API測(cè)試間隔時(shí)間就又會(huì)回到文章最開(kāi)始的兩難境地。

那么如何解決這個(gè)問(wèn)題呢?先來(lái)讓我們剖析一下前面幾種解決方案的共通點(diǎn)。

在上面的場(chǎng)景中,我們都是已知外部API功能來(lái)編寫相應(yīng)的功能測(cè)試,并且使用直接調(diào)用外部API的方式來(lái)達(dá)到驗(yàn)證測(cè)試的目的,這樣就不可避免的帶來(lái)兩個(gè)問(wèn)題:

  • 第一,服務(wù)消費(fèi)方對(duì)服務(wù)提供方API的更改是通過(guò)對(duì)API的測(cè)試來(lái)感知的。
  • 第二,直接依賴于真實(shí)API的測(cè)試效果受限于API的穩(wěn)定性和反映速度。

解決方式首先是依賴關(guān)系的解耦,去掉直接對(duì)外部API的依賴,而是內(nèi)部和外部系統(tǒng)都依賴于一個(gè)雙方共同認(rèn)可的約定—“契約”,并且約定內(nèi)容的變化會(huì)被及時(shí)感知;其次,將系統(tǒng)之間的集成測(cè)試,轉(zhuǎn)換為由契約生成的單元測(cè)試,例如通過(guò)契約描述的內(nèi)容,構(gòu)建測(cè)試替身。這樣,依賴契約的測(cè)試效率優(yōu)于集成測(cè)試,同時(shí)契約替代外部API成為信息變更的載體。

對(duì)于契約來(lái)講,行業(yè)內(nèi)比較成熟的解決方案是基于YAML標(biāo)記語(yǔ)言的Swagger Specification(OpenAPI Specification),或者是基于JSON格式的Pact Specification。

通常的做法是API的提供者使用“契約”的形式,將功能發(fā)布在公共平臺(tái),給調(diào)用方進(jìn)行說(shuō)明和參考,這里我們可以暫時(shí)稱之為Provider-Driven-Contract。這種做法的潛在問(wèn)題是,功能提供方的API返回內(nèi)容是否都滿足所有API調(diào)用者的需求不得而知。所以,針對(duì)這個(gè)問(wèn)題,依賴關(guān)系再一次反轉(zhuǎn),契約測(cè)試就搖身一變成為了Consumer-Driven-Contract test(CDCT), 通過(guò)給API提供方提供契約的形式,來(lái)完成功能的實(shí)現(xiàn)。

難道CDCT成為了問(wèn)題終結(jié)者嗎?請(qǐng)聽(tīng)后面分解。

注: 契約測(cè)試其中一個(gè)的典型應(yīng)用場(chǎng)景是內(nèi)外部系統(tǒng)之間的測(cè)試,另一個(gè)典型的例子是前后端分離后的API測(cè)試,這里不做過(guò)多展開(kāi)。

三、契約測(cè)試的維度

1. 測(cè)試覆蓋范圍對(duì)比(縱向)

  • 單元測(cè)試:對(duì)軟件中的基本組成單位的測(cè)試,大多數(shù)是方法函數(shù)的測(cè)試,運(yùn)行速度快。
  • 契約測(cè)試:對(duì)服務(wù)之間的功能進(jìn)行的測(cè)試,運(yùn)行速度基本與單元測(cè)試相同。
  • E2E 測(cè)試:對(duì)系統(tǒng)前后端或者不同系統(tǒng)之間的集成測(cè)試,大多通過(guò)模擬UI操作的方式實(shí)現(xiàn),運(yùn)行速度三者之中最慢。

2. 測(cè)試效率對(duì)比(橫向)

環(huán)境依賴:

  • 單元測(cè)試:程序集
  • 契約測(cè)試:程序集、依賴契約文件、虛擬路由服務(wù)
  • 端到端測(cè)試:程序集、真實(shí)路由服務(wù)、前端UI
  • 運(yùn)行速度: 單元測(cè)試 > 契約測(cè)試 > 端到端測(cè)試

Pact官方給出的幾個(gè)場(chǎng)景:

適用場(chǎng)景:

  • 團(tuán)隊(duì)能把控開(kāi)發(fā)過(guò)程中的Consumer和Provider端
  • 適合Consumer驅(qū)動(dòng)開(kāi)發(fā)的場(chǎng)景
  • 對(duì)于每個(gè)獨(dú)立的Consumer端,Provider端都能管理好需求。

不適用的場(chǎng)景:

  • 公共API或者是OAuth授權(quán)服務(wù)
  • Provider端和Consumer端沒(méi)有良好的溝通渠道
  • 針對(duì)性能的測(cè)試
  • Provider端的功能性測(cè)試(Pact只測(cè)試內(nèi)容和請(qǐng)求格式)
  • 對(duì)于不同輸入有相同的輸出,并未達(dá)到驗(yàn)證的目的
  • 當(dāng)前測(cè)試輸入需要依賴之前測(cè)試返回的結(jié)果

以上對(duì)比說(shuō)明契約測(cè)試所要解決的問(wèn)題是替代系統(tǒng)之間的集成測(cè)試,通過(guò)契約和單元測(cè)試的方式加速系統(tǒng)運(yùn)行。同時(shí)也說(shuō)明契約測(cè)試存在一些不適用的場(chǎng)景,要依據(jù)使用場(chǎng)景區(qū)別對(duì)待。契約測(cè)試沒(méi)有取代單元測(cè)試以及E2E測(cè)試。

四、契約測(cè)試與CD的整合

最開(kāi)始,我們的pipeline是這樣的,單元測(cè)試是獨(dú)立的測(cè)試,當(dāng)通過(guò)單元測(cè)試后運(yùn)行集成測(cè)試。此時(shí)集成測(cè)試成為了系統(tǒng)瓶頸,而且一旦集成測(cè)試失敗,就必須被迅速修復(fù),其他pipeline只能等待其修復(fù),否則任何新的變更都會(huì)測(cè)試失敗。

一個(gè)解決辦法是將集成測(cè)試分散在每個(gè)pipeline上,每次集成測(cè)試運(yùn)行的版本是當(dāng)前的最新代碼和其他系統(tǒng)的上一次通過(guò)版本之間的測(cè)試。這樣解決了測(cè)試的獨(dú)立性以及不會(huì)阻礙其他pipeline測(cè)試的效果,然后將通過(guò)測(cè)試的不同系統(tǒng)的package按照版本保存。但是這樣一來(lái),集成測(cè)試的缺點(diǎn)就更為明顯提現(xiàn)出來(lái),第一是系統(tǒng)部署時(shí)間長(zhǎng),每次集成測(cè)試需要運(yùn)行同樣的測(cè)試在不同pipeline上,增加了測(cè)試成本和反饋周期。

接下來(lái),我們使用契約測(cè)試替代集成測(cè)試。這樣有幾點(diǎn)好處不僅解決了獨(dú)立測(cè)試的目的,同時(shí)解決了集成測(cè)試慢和部署時(shí)間長(zhǎng)等問(wèn)題。

為了保證契約測(cè)試的正確性,契約文件由Consumer端生成,然后Provider端來(lái)實(shí)現(xiàn)API,我們使用CDCT來(lái)改造我們的pipeline。

我們先假設(shè)B系統(tǒng)希望A系統(tǒng)提供新功能,如果按照?qǐng)D中黃色步驟來(lái)提交的話,則會(huì)測(cè)試失敗,原因在于此時(shí),契約文件是最新的B-A.consumer.1.1.pact與之對(duì)應(yīng)A-B.provider.1.0.jar不是最新的,所以測(cè)試失敗。

按照?qǐng)D中步驟2運(yùn)行,當(dāng)提交A的pipeline時(shí),當(dāng)前版本的A已經(jīng)升級(jí)到1.1,而契約文件還是1.0版本,沒(méi)有break測(cè)試的情況下,最終將A-B.provider.1.1.jar提交到服務(wù)器上。

 

然后按照?qǐng)D中步驟3運(yùn)行,A-B.provider.1.1.jar和B-A.consumer.1.1.pact完美契合,最終又將B-A.consumer.1.1.pact提交到服務(wù)器。所以,改成CDCT之后,雖然產(chǎn)生了一定的提交順序依賴,但是帶來(lái)的更多的好處是確保契約文件的產(chǎn)生是調(diào)用端提出,并且保證當(dāng)前最新,確保系統(tǒng)的正確性。

喜歡思考的同學(xué)不難發(fā)現(xiàn),CDCT存在自身的缺陷,一個(gè)簡(jiǎn)單的例子是當(dāng)B存在一個(gè)已有的契約約束A的一個(gè)功能,當(dāng)B需要A更新其API時(shí),是先提交B的契約測(cè)試,還是更改A的功能到最新版本?其實(shí)二者都不可行。

解決辦法萬(wàn)變不離其宗,就是大家熟悉的不能再熟悉的重構(gòu)心法,由王建總結(jié)的十六字箴言:

[[232073]]

我們分五步來(lái)完成API的更新:

  • Provider端提交一個(gè)新的API來(lái)保證新功能,同時(shí)舊的API功能不變,提交并通過(guò)測(cè)試。
  • 將Consumer端API的調(diào)用指向Provider端的新API,并更新契約文件以約束新功能。
  • 將Provider端舊API同步更新為新API,提交并通過(guò)測(cè)試。
  • 將Consumer端指回舊有API,其他保持不變。
  • 將Provider端臨時(shí)過(guò)渡的新API刪除。

至此,我們解決了API更新時(shí)如何保證契約測(cè)試的提交順序,如果是刪除API,則直接刪除Consumer端的契約測(cè)試即可。

五、需要思考的問(wèn)題

1. 如果并行測(cè)試的話,誰(shuí)先提交成功的版本,另外一個(gè)測(cè)試是否要重新運(yùn)行?

設(shè)想,當(dāng)兩個(gè)并行pipeline A和B,同時(shí)運(yùn)行時(shí),A中跑的是A1.1和B1.0,B中跑的是B1.1和A1.0的測(cè)試,假如雙方均能通過(guò)各自的測(cè)試,但是新版本不兼容(A1.1和B1.1測(cè)試失敗),雙方都將各自的新版本保留,這樣就造成了存在相互不兼容的兩個(gè)版本。目前解決方案是,人為制造一個(gè)“瓶頸”,保證同時(shí)只有一個(gè)契約測(cè)試在運(yùn)行,保存的只有一個(gè)版本。

2. 契約測(cè)試可維護(hù)性如何?

構(gòu)建契約測(cè)試類似于單元測(cè)試,并且在Pact的框架下十分方便維護(hù)。但是,測(cè)試框架本身還有一些問(wèn)題,諸如,大小寫敏感,空值驗(yàn)證,只有一份契約文件,契約測(cè)試分組等。

(以上是基于pact 1.0的實(shí)踐,pact2.0使用了正則表達(dá)式以及TypeMatching等機(jī)制解決了驗(yàn)證“具體”值的問(wèn)題,更多詳細(xì)內(nèi)容請(qǐng)關(guān)注pact官方文檔)

六、結(jié)語(yǔ)

契約測(cè)試不是銀彈,它不是替代E2E測(cè)試的終結(jié)者,更不是單元測(cè)試的升級(jí)換代,它更偏向于服務(wù)和服務(wù)之間的API測(cè)試,通過(guò)解耦服務(wù)依賴關(guān)系和單元測(cè)試來(lái)加快測(cè)試的運(yùn)行效率。

【本文是51CTO專欄作者“ThoughtWorks”的原創(chuàng)稿件,微信公眾號(hào):思特沃克,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來(lái)源: 51CTO專欄
相關(guān)推薦

2018-01-10 14:13:04

測(cè)試矩陣API測(cè)試

2020-01-03 11:04:54

安全測(cè)試滲透

2023-11-04 16:28:54

2023-09-22 17:36:37

2021-01-28 22:31:33

分組密碼算法

2020-05-22 08:16:07

PONGPONXG-PON

2020-08-12 08:34:16

開(kāi)發(fā)安全We

2022-11-26 00:00:06

裝飾者模式Component

2022-10-08 11:33:56

邊緣計(jì)算云計(jì)算

2019-12-17 10:06:18

CDMA高通4G

2022-03-08 16:10:38

Redis事務(wù)機(jī)制

2020-09-08 06:54:29

Java Gradle語(yǔ)言

2022-03-29 09:56:21

游戲版本運(yùn)營(yíng)

2021-01-01 09:01:05

前端組件化設(shè)計(jì)

2020-06-28 09:30:37

Linux內(nèi)存操作系統(tǒng)

2023-07-26 07:24:07

2021-08-04 09:32:05

Typescript 技巧Partial

2021-01-29 08:32:21

數(shù)據(jù)結(jié)構(gòu)數(shù)組

2021-02-06 08:34:49

函數(shù)memoize文檔

2022-08-08 08:25:21

Javajar 文件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)