
有近兩周沒有在公眾號(hào)中發(fā)表文章了,看過我之前公眾號(hào)的讀者都知道,公眾號(hào)中近期在連載《RobotFramework接口自動(dòng)化系列課程》,原本計(jì)劃每周更新一篇,最近由于博主在帶一個(gè)新項(xiàng)目,實(shí)在是沒空抽出時(shí)間來,所以向公眾號(hào)中對(duì)連載課程一直期待的讀者說聲抱歉。 由于最近帶微服務(wù)的項(xiàng)目,而對(duì)于微服務(wù)其實(shí)也是近從14年才流行起來,對(duì)于這塊目前網(wǎng)上的干貨內(nèi)容還是較少,借著機(jī)會(huì),小結(jié)一下知識(shí)點(diǎn)。所以今天也先不打算連載《RobotFramework接口自動(dòng)化系列課程》,如果讀者對(duì)連載的課程比較熱衷的話,可以在留言板下面給筆者留言,如果讀者反饋較多的話,博主也會(huì)適當(dāng)加快調(diào)整課程分享節(jié)奏。 下面就給大家淺聊一下微服務(wù)架構(gòu)下的契約測(cè)試。 Microservice微服務(wù)是一種架構(gòu)風(fēng)格,我們可以把每一個(gè)微服務(wù)視做一個(gè)用一組API提供業(yè)務(wù)功能的組件,且服務(wù)之間會(huì)有很多依賴關(guān)系,如下圖所示:
 
這些服務(wù)之間可能由一個(gè)團(tuán)隊(duì)或者相互獨(dú)立的團(tuán)隊(duì)開發(fā)和維護(hù),并且它們?cè)谙到y(tǒng)內(nèi)部相互依賴,在這種情況下,接口的開發(fā)和維護(hù)可能會(huì)帶來一些問題,例如服務(wù)端調(diào)整架構(gòu)或接口調(diào)整而對(duì)消費(fèi)者不透明,導(dǎo)致接口調(diào)用失敗。

注:關(guān)于微服務(wù)的基本組件組成及介紹,后面考慮單獨(dú)抽離一篇文章進(jìn)行介紹,本文就不過多說了~ 例如, 我們想測(cè)試某微服務(wù)架構(gòu)中的某一個(gè)服務(wù)時(shí),比如下圖第一排中間的服務(wù),如:
 因?yàn)樗推渌?wù)都存在交互,一般我們有兩種方式: 下面分析一下這兩種方式優(yōu)缺點(diǎn): 對(duì)比分析 | 優(yōu)點(diǎn) | 缺點(diǎn) |
---|
第一種方式:部署所有服務(wù) | 1、模擬生成環(huán)境 2、可以真實(shí)地測(cè)試服務(wù)交互 | 1、測(cè)試其中一個(gè)服務(wù),不是不布署全部服務(wù),包括各基礎(chǔ)設(shè)施 2、要運(yùn)行很長(zhǎng)時(shí)間 3、不能及時(shí)給予測(cè)試反饋 4、測(cè)試環(huán)境被一個(gè)測(cè)試服務(wù)鎖定,別人無法同時(shí)使用。 | 第二種方式:Mock其它服務(wù) | 1、測(cè)試反饋快 2、沒有基礎(chǔ)服務(wù)依賴要求 | 1、服務(wù)的實(shí)現(xiàn)方創(chuàng)建的Stubs,可能實(shí)現(xiàn)與這個(gè)無關(guān) 2、無法模擬真實(shí)數(shù)據(jù)交互環(huán)境 |
常規(guī)我們開發(fā)的項(xiàng)目主要由服務(wù)提供方約定接口,雖然提供方架構(gòu)調(diào)整或改變接口之前通常會(huì)通知消費(fèi)者,但可能還是會(huì)存在遺漏。 當(dāng)一個(gè)Service已經(jīng)同時(shí)被多個(gè)使用者調(diào)用用的時(shí)候,怎么保證service的修改對(duì)其它所有使用者造成影響都被感知到呢? 那么契約測(cè)試的引出就是為了解決這類問題的最佳方案! 契約測(cè)試 ,又稱之為 消費(fèi)者驅(qū)動(dòng)的契約測(cè)試(Consumer-Driven Contracts,簡(jiǎn)稱CDC),根據(jù) 消費(fèi)者驅(qū)動(dòng)契約 ,我們可以將服務(wù)分為消費(fèi)者端和生產(chǎn)者端,而消費(fèi)者驅(qū)動(dòng)的契約測(cè)試的核心思想在于是從消費(fèi)者業(yè)務(wù)實(shí)現(xiàn)的角度出發(fā),由消費(fèi)者自己會(huì)定義需要的數(shù)據(jù)格式以及交互細(xì)節(jié),并驅(qū)動(dòng)生成一份契約文件。然后生產(chǎn)者根據(jù)契約文件來實(shí)現(xiàn)自己的邏輯,并在持續(xù)集成環(huán)境中持續(xù)驗(yàn)證。 后文中消費(fèi)者驅(qū)動(dòng)的契約測(cè)試統(tǒng)一用cdc來代替。 cdc核心原則: cdc是以消費(fèi)者提出接口契約,交由服務(wù)提供方實(shí)現(xiàn),并以測(cè)試用例對(duì)契約進(jìn)行產(chǎn)生約束,所以服務(wù)提供方在滿足測(cè)試用例的情況下可以自行更改接口或架構(gòu)實(shí)現(xiàn)而不影響消費(fèi)者。 cdc是一種針對(duì)外部服務(wù)的接口進(jìn)行的測(cè)試,它能夠驗(yàn)證服務(wù)是否滿足消費(fèi)方期待的契約。 它的本質(zhì)是從利益相關(guān)者的目標(biāo)和動(dòng)機(jī)出發(fā),最大限度地滿足需求方的業(yè)務(wù)價(jià)值實(shí)現(xiàn)。
單元測(cè)試 | 單元測(cè)試針對(duì)代碼單元(通常是類)的測(cè)試,單元測(cè)試的價(jià)值在于能提供最快的反饋。另外好的單元測(cè)試還可以幫助你改善設(shè)計(jì),在你的團(tuán)隊(duì)掌握TDD的前提下,單元測(cè)試能輔助重構(gòu),幫助改善代碼整潔度。 |
---|
API測(cè)試 | API測(cè)試是針對(duì)業(yè)務(wù)接口進(jìn)行的測(cè)試,主要測(cè)內(nèi)部接口功能實(shí)現(xiàn)是否完整,比如說內(nèi)部邏輯是不是正常,異常處理是不是正確。 | 契約測(cè)試 | 契約測(cè)試其實(shí)是為了測(cè)試服務(wù)之間連接或者說接口調(diào)用的正確性,為了驗(yàn)證服務(wù)提供者的功能是不是真正能夠滿足消費(fèi)者的需求。它其實(shí)體現(xiàn)了測(cè)試前移的思想,把本來要通過集成測(cè)試才能驗(yàn)證的工作化作單元測(cè)試和接口測(cè)試,用更輕量的方式快速進(jìn)行驗(yàn)證。 | 集成測(cè)試 | 它從用戶的角度驗(yàn)證整個(gè)功能的正確性,測(cè)的是端到端的流程,并且加入用戶場(chǎng)景和數(shù)據(jù),驗(yàn)證整個(gè)過程是不是OK,它的價(jià)值業(yè)務(wù)價(jià)值最高,是驗(yàn)證一個(gè)完整的流程。 |
聯(lián)調(diào)成本過高,要雙方開發(fā)到某一階段后放在同一個(gè)環(huán)境上才能進(jìn)行,要同時(shí)把握雙方的進(jìn)度,造成資源和時(shí)間上的浪費(fèi)。 對(duì)于接口的變動(dòng)把控相當(dāng)困難。由于接口變動(dòng)是普遍存在的,尤其對(duì)于調(diào)用關(guān)系復(fù)雜的接口,一旦發(fā)生變動(dòng),如果沒有一套機(jī)制進(jìn)行控制,驗(yàn)證的成本巨大。 接口不匹配”是指服務(wù)依賴于彼此間的接口進(jìn)行通信,如何保證改變一個(gè)服務(wù)的接口會(huì)對(duì)其他所有依賴服務(wù)是否造成造成影響。 在發(fā)生契約變化時(shí),提供一種可立即被服務(wù)端和消費(fèi)端發(fā)現(xiàn)的方式。
通過使用契約測(cè)試,接口調(diào)用雙方協(xié)商接口后就可以并行開發(fā),并且在開發(fā)過程中就利用契約進(jìn)行預(yù)集成測(cè)試,不用等到聯(lián)調(diào)再來集成調(diào)通接口,一旦成熟,在保證質(zhì)量的前提下,聯(lián)調(diào)的成本可以減低到幾乎為0。 因?yàn)槠跫s的存在,讓接口的變動(dòng)有跡可循,即使變動(dòng)也可以確保變動(dòng)的安全性和準(zhǔn)確性。 通過契約測(cè)試,團(tuán)隊(duì)能以一種離線的方式(不需要消費(fèi)者、提供者同時(shí)在線),通過契約作為中間的標(biāo)準(zhǔn),驗(yàn)證提供者提供的內(nèi)容是否滿足消費(fèi)者的期望。
Consumer: 微服務(wù)接口的調(diào)用者 Provider: 微服務(wù)接口的提供者 契約文件: 是由consumer端和provider端共同定義的接口規(guī)范,包括接口訪問的路徑,輸入和輸出數(shù)據(jù)。在具體的實(shí)施中,是由consumer端生成的一個(gè)json文件,并存放在pact broker上 Pact Broker: 保存契約文件的服務(wù)器 注:通常在工程實(shí)踐上,當(dāng)消費(fèi)者根據(jù)需要生成了契約之后,我們會(huì)將契約上傳至一個(gè)公共可訪問的地址,然后生產(chǎn)者在執(zhí)行時(shí)會(huì)訪問這個(gè)地址,并獲得最新版本的契約,然后對(duì)著這些契約來執(zhí)行相應(yīng)的驗(yàn)證過程。
9.2 Pact 基本流程
簡(jiǎn)要流程: 第一步在消費(fèi)者端Consumer端寫一個(gè)對(duì)接口發(fā)送請(qǐng)求的單元測(cè)試,在運(yùn)行這個(gè)單元測(cè)試的時(shí)候,Pact會(huì)將服務(wù)提供者自動(dòng)用一個(gè)MockService代替,并自動(dòng)生成契約文件,這個(gè)契約文件是Json形式的。 第二步在Provider端做契約驗(yàn)證測(cè)試,將Provider服務(wù)啟動(dòng)起來以后,通過pact插件可以運(yùn)行一個(gè)命令,比如你是用maven,就是mvn pact:verify,它會(huì)自動(dòng)按照契約生成接口請(qǐng)求并驗(yàn)證接口響應(yīng)是否滿足契約中的預(yù)期,所以可以看到這個(gè)過程中,在消費(fèi)者端不用啟動(dòng)Provider,在服務(wù)提供端不用啟動(dòng)Consumer,卻完成了與集成測(cè)試類似的驗(yàn)證。
詳細(xì)流程: 基于消費(fèi)者的業(yè)務(wù)邏輯,驅(qū)動(dòng)出契約 其實(shí)現(xiàn)步驟如下所示: 1、使用Pact的DSL,定義Mock提供者,如localhost:8080 2、將Mock地址傳給消費(fèi)者并對(duì)Mock的提供者發(fā)送請(qǐng)求。 3、使用Pact的DSL,定義響應(yīng)內(nèi)容(包括Headers、Status以及Body等)。 4、在消費(fèi)者端 使用@PactVerification運(yùn)行單元測(cè)試(Pact集成了JUnit、RSpec等框架),生成契約文件。 5、當(dāng)運(yùn)行測(cè)試后,Pact框架記錄消費(fèi)者的名稱、發(fā)送的請(qǐng)求、期望的響應(yīng)以及元數(shù)據(jù),將其保存為當(dāng)前場(chǎng)景下的契約文件,通常命名為[Consumer]-[Provider].json,例如 orderConsumer-orderProvider.json 6、契約文件生成后,我們可以將其保存在文件系統(tǒng)或者Pact-Broker(Pact提供的中間件,用來管理契約文件)中,以便后續(xù)提供者使用。 基于消費(fèi)者驅(qū)動(dòng)出的契約,對(duì)提供者進(jìn)行驗(yàn)證 在提供者端,我們不需要寫任何驗(yàn)證的相關(guān)代碼,Pact已經(jīng)提供了驗(yàn)證的接口,我們只需要做好如下配置: 1、為提供者指定契約文件的存儲(chǔ)源(如文件系統(tǒng)或者Pact-Broker)。 2、啟動(dòng)提供者,運(yùn)行PactVerify(Pact有Maven、Gradle或者Rake插件,提供pactVerify命令)。 3、當(dāng)執(zhí)行pactVerify時(shí),Pact將按照如下步驟,自動(dòng)完成對(duì)提供者的驗(yàn)證: 構(gòu)建Mock的消費(fèi)者。 4、根據(jù)契約文件記錄的請(qǐng)求內(nèi)容,向提供者發(fā)送請(qǐng)求。 5、從提供者獲取響應(yīng)結(jié)果。 6、驗(yàn)證提供者的響應(yīng)結(jié)果與Pact契約文件定義的契約中是否一致。 9.3 Pact 特性 傳統(tǒng)情況下做集成測(cè)試需要把服務(wù)消費(fèi)者和服務(wù)提供者兩個(gè)服務(wù)都啟動(dòng)起來再進(jìn)行測(cè)試,而Pact做契約測(cè)試時(shí)將它分成兩步來做,每一步里面都不需要同時(shí)啟動(dòng)兩個(gè)服務(wù)。 1、測(cè)試解耦,就是服務(wù)消費(fèi)與提供者解耦,甚至可以在沒有提供者實(shí)現(xiàn)的情況下開始消費(fèi)者的測(cè)試。 2、一致性,通過測(cè)試保證契約與現(xiàn)實(shí)是一致性的。 3、測(cè)試前移,可以在開發(fā)階段運(yùn)行,并作為CI的一部分,甚至在開發(fā)本地就可以去做,而且可以看到一條命令就可以完成,便于盡早發(fā)現(xiàn)問題,降低解決問題的成本。 4、Pact提供的Pact Broker 可以自動(dòng)生成一個(gè)服務(wù)調(diào)用關(guān)系圖,為團(tuán)隊(duì)提供了全局的服務(wù)依賴關(guān)系圖。 5、Pact提供Pact Broker這個(gè)工具來完成契約文件管理,使用Pact Broker后,契約上傳與驗(yàn)證都可以通過命令完成,且契約文件可以制定版本。 6、使用Pact這類框架,能有效幫助團(tuán)隊(duì)降低服務(wù)間的集成測(cè)試成本,盡早驗(yàn)證當(dāng)提供者接口被修改時(shí),是否破壞了消費(fèi)者的期望。 7、Pact目前僅支持REST HTTP 通信,但對(duì)于RPC的通信機(jī)制,暫不支持。 注:寫到最后,夜也深了,如果你覺得本文對(duì)你有點(diǎn)啟發(fā)或者作用,歡迎打賞支持一下~
|