別再加端到端集成測(cè)試了,快換契約測(cè)試吧
正如大家所知,最初QA都是手動(dòng)執(zhí)行測(cè)試用例,開(kāi)發(fā)人員每修改一個(gè)版本,QA就要手動(dòng)測(cè)試一遍,隨著功能的不斷增加,手動(dòng)測(cè)試重復(fù)的工作量越來(lái)越大。為了解脫QA重復(fù)性勞動(dòng),提高工作效率,重復(fù)執(zhí)行的測(cè)試用例被自動(dòng)化了。自動(dòng)化測(cè)試讓QA的工作前進(jìn)了一大步。
本文講的端到端集成測(cè)試(簡(jiǎn)稱(chēng)集成測(cè)試)是指系統(tǒng)集成后的自動(dòng)化測(cè)試,是系統(tǒng)或模塊真實(shí)組裝后運(yùn)行的測(cè)試。很多團(tuán)隊(duì)用UI端到端來(lái)測(cè)系統(tǒng)集成后的行為,這類(lèi)工具很多,比如有Selenium webdriver等。端到端的集成測(cè)試反饋與修復(fù)的周期比較長(zhǎng)、運(yùn)行速度慢,測(cè)試運(yùn)行不穩(wěn)定,有時(shí)隨機(jī)失敗,維護(hù)成本也很高。它不像單元測(cè)試,單元測(cè)試測(cè)具體一個(gè)方法或API,定位準(zhǔn)確,采用Mock機(jī)制,運(yùn)行速度非???毫秒級(jí)),又是開(kāi)發(fā)人員在本地執(zhí)行,反饋修復(fù)及時(shí),成本較低。
于是,我們把絕大部分能在單元測(cè)試?yán)锔采w的用例都放在單元測(cè)試覆蓋,只有單元測(cè)試測(cè)不了的(比如模塊或API之間連通性),才會(huì)通過(guò)端到端的集成測(cè)試來(lái)覆蓋。此時(shí),測(cè)試又前進(jìn)了一大步。
但是,隨著業(yè)務(wù)的不斷拓展、產(chǎn)品功能不斷增加,系統(tǒng)架構(gòu)越來(lái)越復(fù)雜,端對(duì)端集成測(cè)試的成本越來(lái)越高,測(cè)試用例也越增越多,集成測(cè)試又成了快速驗(yàn)證的阻塞區(qū)。在當(dāng)今持續(xù)集成的開(kāi)發(fā)模式中,開(kāi)發(fā)團(tuán)隊(duì)會(huì)頻繁集成,每次集成都會(huì)通過(guò)流水線(xiàn)(Pipeline)快速驗(yàn)證、準(zhǔn)備部署包、進(jìn)而發(fā)布。然而,集成測(cè)試的這些問(wèn)題會(huì)嚴(yán)重影響或阻礙產(chǎn)品快速發(fā)布。
那么問(wèn)題來(lái)了,怎么解決集成測(cè)試的現(xiàn)有問(wèn)題,讓測(cè)試再前進(jìn)一大步?
其實(shí),早在幾年前,著名的敏捷和TDD專(zhuān)家JB Rainsberger就提到了。
集成測(cè)試是個(gè)騙局”,正確的是應(yīng)該用一種契約或協(xié)議測(cè)試來(lái)測(cè)試集成后的系統(tǒng)行為! |
JB Rainsberger認(rèn)為你寫(xiě)的2-5%的集成測(cè)試和單元測(cè)試有重復(fù),或者和其它地方的集成測(cè)試存在重復(fù),而且當(dāng)集成測(cè)試失敗時(shí),你也不知道發(fā)生了什么,不能及時(shí)準(zhǔn)確定位問(wèn)題。
JB Rainsberger認(rèn)為應(yīng)該讓契約測(cè)試來(lái)替代集成測(cè)試,那么,什么是契約測(cè)試?它是否能解決集成測(cè)試的這些問(wèn)題?
契約測(cè)試
契約測(cè)試是驗(yàn)證服務(wù)的Provider是否按照期望的方式與服務(wù)的Consumer進(jìn)行交互,簡(jiǎn)單的說(shuō)是Consumer與Provider兩者之間的集成。
而Contract即合同、契約,就是Provider與Consumer的交互方式。
契約測(cè)試通常是基于Consumer驅(qū)動(dòng)的(Consumer Driven Contracts,基于Consumer驅(qū)動(dòng)的契約測(cè)試工具有PACT)。基于Consumer驅(qū)動(dòng)的契約測(cè)試分兩個(gè)階段:
- Consumer生成契約,開(kāi)發(fā)者在Consumer端寫(xiě)測(cè)試時(shí)Mock掉Provider,運(yùn)行測(cè)試生成契約文件;
- Provider驗(yàn)證契約,開(kāi)發(fā)者拿契約文件直接在Provider端運(yùn)行測(cè)試進(jìn)行驗(yàn)證。
第一階段:Consumer生成契約
第二階段:Provider驗(yàn)證契約
如何用PACT編寫(xiě)契約測(cè)試,這里就不贅述了,實(shí)例詳情請(qǐng)參見(jiàn)PACT an example。
集成測(cè)試的特點(diǎn):
- 真實(shí)安裝后測(cè)試,測(cè)試更接近真實(shí)使用情況;
- 可見(jiàn)性強(qiáng),容易理解;(比如:看一遍運(yùn)行關(guān)鍵業(yè)務(wù)的集成測(cè)試,業(yè)務(wù)人員或客戶(hù)會(huì)覺(jué)得很放心。也可以替代驗(yàn)收測(cè)試)
- 模塊真實(shí)調(diào)用,測(cè)試運(yùn)行慢,秒級(jí)別或分鐘級(jí)別,反饋與修復(fù)的周期慢,成本高;
- 問(wèn)題定位難,多個(gè)子模塊組合安裝后的測(cè)試,很難定位是哪個(gè)模塊出的問(wèn)題;
- 真實(shí)的安裝或環(huán)境搭建,不穩(wěn)定,容易導(dǎo)致測(cè)試隨機(jī)失敗;
- 溝通成本高,需要不同模塊團(tuán)隊(duì)間的協(xié)調(diào)工作;
- 與底層測(cè)試或集成測(cè)試會(huì)有重復(fù),集成測(cè)試中有的路徑已經(jīng)被單元測(cè)試覆蓋。
契約測(cè)試的特點(diǎn):
- 開(kāi)發(fā)人編寫(xiě),采用Mock機(jī)制,開(kāi)發(fā)本地就可以運(yùn)行,沒(méi)有真實(shí)調(diào)用,運(yùn)行快,毫秒級(jí)修復(fù)反饋周期短;
- Provider與Consumer兩兩之間的驗(yàn)證,容易定位問(wèn)題,而且與底層測(cè)試或其它契約之間沒(méi)有重復(fù);
- 不需要部署真實(shí)的集成環(huán)境,穩(wěn)定且成功率高;
- 溝通成本低。(比如一個(gè)Consumer端的加入導(dǎo)致服務(wù)端API修改,服務(wù)端開(kāi)發(fā)人員不必跑去找所有其它Consumer端開(kāi)發(fā)人員溝通確認(rèn)是否會(huì)被影響,直接運(yùn)行契約測(cè)試就能知道結(jié)果。)
由此可見(jiàn),開(kāi)篇談到的端到端集成測(cè)試運(yùn)行慢、不穩(wěn)定、修復(fù)反饋周期長(zhǎng)等等問(wèn)題,都能通過(guò)契約測(cè)試得到解決或改進(jìn)。
舉例說(shuō)明
假如某社交聊天產(chǎn)品(簡(jiǎn)稱(chēng)TWChat)的架構(gòu)是這樣的:服務(wù)端、客戶(hù)端、郵件通知服務(wù)三部分組成。
架構(gòu)圖
通常的測(cè)試策略:底層絕大部分的單元測(cè)試+少量上層端到端集成測(cè)試。
用TWChat注冊(cè)場(chǎng)景來(lái)舉例說(shuō)明吧。注冊(cè)一個(gè)帳號(hào)的工作流是:客戶(hù)端把注冊(cè)帳號(hào)信息提交給服務(wù)端,服務(wù)端處理帳號(hào)時(shí),會(huì)去調(diào)用郵件通知服務(wù)發(fā)通知,并完成注冊(cè)。
底層單元測(cè)試用例
單元測(cè)試
- 客戶(hù)端的單元測(cè)試:驗(yàn)證注冊(cè)表各個(gè)Field的各種輸入組合、以及檢驗(yàn)正確性等;(比如:邊界值、空、中英數(shù)各類(lèi)組合、合法與非法輸入等)
- 服務(wù)端的單元測(cè)試:驗(yàn)證注冊(cè)數(shù)據(jù)表的各種輸入組合可以成功存放于服務(wù)端帳號(hào)DB表中,且不合法的、重復(fù)等會(huì)有相應(yīng)的錯(cuò)誤碼;
- 郵箱通知服務(wù)端的單元測(cè)試:輸入合法的各類(lèi)不同的郵箱確,保證能正常發(fā)出通知郵件并返回正確碼,輸入不合法的郵箱或空郵箱確保有相應(yīng)的錯(cuò)誤碼。
上層端到端集成測(cè)試用例
集成測(cè)試
一條注冊(cè)連通性的Happy path測(cè)試用例, 輸入所有必填項(xiàng)提交,驗(yàn)證注冊(cè)成功,收到成功通知郵件。
以上的集成測(cè)試,必填項(xiàng)輸入其實(shí)是與單元測(cè)試重復(fù),郵件通知發(fā)送功能與單元測(cè)試也有重復(fù);再者,這條集成測(cè)試跑失敗,我們并不能定位是客戶(hù)端的問(wèn)題、服務(wù)端問(wèn)題、還是通知服務(wù)的問(wèn)題。加上集成測(cè)試是把所有子模塊(服務(wù)端、客戶(hù)端、通知微服務(wù))真實(shí)產(chǎn)品安裝包部署以后才能運(yùn)行的測(cè)試,反饋、修改周期長(zhǎng),不穩(wěn)定容易隨機(jī)失敗等等。
集成測(cè)試換成契約測(cè)試用例
契約測(cè)試
- TWChat客戶(hù)端Consumer與TWChat服務(wù)端Provider加一條契約測(cè)試,確保TWChat服務(wù)端按期望提供給客戶(hù)端接口(參見(jiàn)PACT an example)。
- TWChat服務(wù)端Consumer與郵件通知服務(wù)Provider之間加一條契約測(cè)試,確保郵件通知服務(wù)按照預(yù)期與TWChat服務(wù)端交互(參見(jiàn)PACT an example)。
契約測(cè)試與單元測(cè)試以及其它測(cè)試之間沒(méi)有重復(fù),它是單純驗(yàn)證Provider與Consumer之間按預(yù)期的方式交互,定位準(zhǔn)確;不需要部署真實(shí)的系統(tǒng)環(huán)境、Mock機(jī)制、沒(méi)有真實(shí)API調(diào)用,運(yùn)行非???、反饋及時(shí)、修復(fù)周期短、成本低,在這種情況下,自動(dòng)化測(cè)試流水線(xiàn)運(yùn)行更快了,產(chǎn)品流水線(xiàn)出產(chǎn)品安裝包也更快。因此,顯然契約測(cè)試才是真正對(duì)的選擇。
微服務(wù)架構(gòu)下契約測(cè)試的重要性
例如,隨著TWChat業(yè)務(wù)的擴(kuò)大,TWChat錢(qián)包,TWChat安卓端,TWChat iOS端,以及其它的服務(wù)方與Consumer方接入TWChat服務(wù)器。
當(dāng)其中TWChat安卓端修改后,如果還按照之前的集成測(cè)試方式,就得把服務(wù)端與所有的客戶(hù)端真實(shí)的集成到一起測(cè)試,確保都沒(méi)有被影響才能生成產(chǎn)品安裝包并發(fā)布,這里的集成測(cè)試成了流水線(xiàn)(pipeline)的一個(gè)聚集地,也成為了產(chǎn)品發(fā)布的阻塞區(qū)。
集成測(cè)試流水線(xiàn)
假如,換成契約測(cè)試,我們把契約測(cè)試放在各自的流水線(xiàn)(pipeline)上,每次代碼提交觸發(fā)相應(yīng)產(chǎn)品流水線(xiàn)上的契約測(cè)試,當(dāng)TWChat安卓客戶(hù)端Consumer API修改,在安卓客戶(hù)端的流水線(xiàn)(pipeline)上運(yùn)行安卓客戶(hù)端為Consumer與服務(wù)端為Provider的契約測(cè)試,測(cè)試通過(guò),生成產(chǎn)品安裝包;如果契約測(cè)試失敗,服務(wù)端需要相應(yīng)修改,則本次TWChat安卓端的安裝包需要在TWChat服務(wù)端修改后,方可生成安卓客戶(hù)端的產(chǎn)品安裝包。
契約測(cè)試解耦后
由此可見(jiàn),并不是每一次TWChat安卓端的修改都要全部Consumer端與服務(wù)端集成后驗(yàn)證才出包,而是各自可以獨(dú)立出包,產(chǎn)品解耦,大大節(jié)省時(shí)間,提高出包頻率。
并非所有端到端集成測(cè)試都適合換成契約測(cè)試
契約測(cè)試相比端到端集成測(cè)試有很多優(yōu)勢(shì),但并不是所有場(chǎng)景都適合契約而非集成測(cè)試。
比如:
- 契約測(cè)試無(wú)法做安全或性能測(cè)試等。
- 契約測(cè)試采用Mock機(jī)制,所以沒(méi)有集成測(cè)試更接近真實(shí)環(huán)境,也不能給業(yè)務(wù)人員做驗(yàn)收,可視性差。
- 契約測(cè)試基于不同的服務(wù)使用的協(xié)議不同,驗(yàn)證契約的復(fù)雜度會(huì)不同,復(fù)雜度過(guò)高時(shí),需要權(quán)衡是否有必要加契約測(cè)試。
所以,把端到端集成測(cè)試要換成契約測(cè)試也不是絕對(duì)的,視情況而定。
總的來(lái)說(shuō),當(dāng)你追加端到端集成測(cè)試的時(shí)候,如非特殊,快換契約測(cè)試吧。
【本文是51CTO專(zhuān)欄作者“ThoughtWorks”的原創(chuàng)稿件,微信公眾號(hào):思特沃克,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】