有近兩週沒有在公衆號中發表文章了,看過我以前公衆號的讀者都知道,公衆號中近期在連載《RobotFramework接口自動化系列課程》,本來計劃每週更新一篇,最近因爲博主在帶一個新項目,實在是沒空抽出時間來,因此向公衆號中對連載課程一直期待的讀者說聲抱歉。json
因爲最近帶微服務的項目,而對於微服務其實也是近從14年才流行起來,對於這塊目前網上的乾貨內容仍是較少,藉着機會,小結一下知識點。因此今天也先不打算連載《RobotFramework接口自動化系列課程》,若是讀者對連載的課程比較熱衷的話,能夠在留言板下面給筆者留言,若是讀者反饋較多的話,博主也會適當加快調整課程分享節奏。c#
下面就給你們淺聊一下微服務架構下的契約測試。安全
Microservice微服務是一種架構風格,咱們能夠把每個微服務視作一個用一組API提供業務功能的組件,且服務之間會有不少依賴關係,以下圖所示: 服務器
這些服務之間可能由一個團隊或者相互獨立的團隊開發和維護,而且它們在系統內部相互依賴,在這種狀況下,接口的開發和維護可能會帶來一些問題,例如服務端調整架構或接口調整而對消費者不透明,致使接口調用失敗。架構
注:關於微服務的基本組件組成及介紹,後面考慮單獨抽離一篇文章進行介紹,本文就不過多說了~框架
例如, 咱們想測試某微服務架構中的某一個服務時,好比下圖第一排中間的服務,如:
由於它和其餘服務都存在交互,通常咱們有兩種方式:maven
部署全部的服務來實現端到端測試。ide
在集成測試中Mock其餘服務。微服務
下面分析一下這兩種方式優缺點:工具
對比分析 | 優勢 | 缺點 |
---|---|---|
第一種方式:部署全部服務 | 一、模擬生成環境 二、能夠真實地測試服務交互 |
一、測試其中一個服務,不是不佈署所有服務,包括各基礎設施 二、要運行很長時間 三、不能及時給予測試反饋 四、測試環境被一個測試服務鎖定,別人沒法同時使用。 |
第二種方式:Mock其它服務 | 一、測試反饋快 二、沒有基礎服務依賴要求 |
一、服務的實現方建立的Stubs,可能實現與這個無關 二、沒法模擬真實數據交互環境 |
常規咱們開發的項目主要由服務提供方約定接口,雖然提供方架構調整或改變接口以前一般會通知消費者,但可能仍是會存在遺漏。
當一個Service已經同時被多個使用者調用用的時候,怎麼保證service的修改對其它全部使用者形成影響都被感知到呢?
那麼契約測試的引出就是爲了解決這類問題的最佳方案!
契約測試 ,又稱之爲 消費者驅動的契約測試(Consumer-Driven Contracts,簡稱CDC),根據 消費者驅動契約 ,咱們能夠將服務分爲消費者端和生產者端,而消費者驅動的契約測試的核心思想在因而從消費者業務實現的角度出發,由消費者本身會定義須要的數據格式以及交互細節,並驅動生成一份契約文件。而後生產者根據契約文件來實現本身的邏輯,並在持續集成環境中持續驗證。
後文中消費者驅動的契約測試統一用cdc來代替。
cdc核心原則:
cdc是以消費者提出接口契約,交由服務提供方實現,並以測試用例對契約進行產生約束,因此服務提供方在知足測試用例的狀況下能夠自行更改接口或架構實現而不影響消費者。
cdc是一種針對外部服務的接口進行的測試,它可以驗證服務是否知足消費方期待的契約。 它的本質是從利益相關者的目標和動機出發,最大限度地知足需求方的業務價值實現。
API測試和單元測試,更強調的是覆蓋API內部邏輯。
契約測試,更強調是組件之間鏈接的正確性,除了保證組件內部,還要保證組件間的調用是正確的,也就是服務API之間的調用。
單元測試 | 單元測試針對代碼單元(一般是類)的測試,單元測試的價值在於能提供最快的反饋。另外好的單元測試還能夠幫助你改善設計,在你的團隊掌握TDD的前提下,單元測試能輔助重構,幫助改善代碼整潔度。 |
---|---|
API測試 | API測試是針對業務接口進行的測試,主要測內部接口功能實現是否完整,好比說內部邏輯是否是正常,異常處理是否是正確。 |
契約測試 | 契約測試實際上是爲了測試服務之間鏈接或者說接口調用的正確性,爲了驗證服務提供者的功能是否是真正可以知足消費者的需求。它其實體現了測試前移的思想,把原本要經過集成測試才能驗證的工做化做單元測試和接口測試,用更輕量的方式快速進行驗證。 |
集成測試 | 它從用戶的角度驗證整個功能的正確性,測的是端到端的流程,而且加入用戶場景和數據,驗證整個過程是否是OK,它的價值業務價值最高,是驗證一個完整的流程。 |
聯調成本太高,要雙方開發到某一階段後放在同一個環境上才能進行,要同時把握雙方的進度,形成資源和時間上的浪費。
對於接口的變更把控至關困難。因爲接口變更是廣泛存在的,尤爲對於調用關係複雜的接口,一旦發生變更,若是沒有一套機制進行控制,驗證的成本巨大。
接口不匹配」是指服務依賴於彼此間的接口進行通訊,如何保證改變一個服務的接口會對其餘全部依賴服務是否形成形成影響。
在發生契約變化時,提供一種可當即被服務端和消費端發現的方式。
下降服務集成的難度,把服務集成這個過程分解成了單元測試和接口測試來作,它從消費者的需求爲出發點,把消費者的需求做爲你的測試用例驅動出一份契約,而後驗證提供者端的功能。
經過使用契約測試,接口調用雙方協商接口後就能夠並行開發,而且在開發過程當中就利用契約進行預集成測試,不用等到聯調再來集成調通接口,一旦成熟,在保證質量的前提下,聯調的成本能夠減低到幾乎爲0。
由於契約的存在,讓接口的變更有跡可循,即便變更也能夠確保變更的安全性和準確性。
經過契約測試,團隊能以一種離線的方式(不須要消費者、提供者同時在線),經過契約做爲中間的標準,驗證提供者提供的內容是否知足消費者的指望。
Consumer: 微服務接口的調用者
Provider: 微服務接口的提供者
契約文件: 是由consumer端和provider端共同定義的接口規範,包括接口訪問的路徑,輸入和輸出數據。在具體的實施中,是由consumer端生成的一個json文件,並存放在pact broker上
Pact Broker: 保存契約文件的服務器
注:一般在工程實踐上,當消費者根據須要生成了契約以後,咱們會將契約上傳至一個公共可訪問的地址,而後生產者在執行時會訪問這個地址,並得到最新版本的契約,而後對着這些契約來執行相應的驗證過程。
第一步在消費者端Consumer端寫一個對接口發送請求的單元測試,在運行這個單元測試的時候,Pact會將服務提供者自動用一個MockService代替,並自動生成契約文件,這個契約文件是Json形式的。
第二步在Provider端作契約驗證測試,將Provider服務啓動起來之後,經過pact插件能夠運行一個命令,好比你是用maven,就是mvn pact:verify,它會自動按照契約生成接口請求並驗證接口響應是否知足契約中的預期,因此能夠看到這個過程當中,在消費者端不用啓動Provider,在服務提供端不用啓動Consumer,卻完成了與集成測試相似的驗證。
基於消費者的業務邏輯,驅動出契約
其實現步驟以下所示:
一、使用Pact的DSL,定義Mock提供者,如localhost:8080
二、將Mock地址傳給消費者並對Mock的提供者發送請求。
三、使用Pact的DSL,定義響應內容(包括Headers、Status以及Body等)。
四、在消費者端 使用@PactVerification運行單元測試(Pact集成了JUnit、RSpec等框架),生成契約文件。
五、當運行測試後,Pact框架記錄消費者的名稱、發送的請求、指望的響應以及元數據,將其保存爲當前場景下的契約文件,一般命名爲[Consumer]-[Provider].json,例如 orderConsumer-orderProvider.json
六、契約文件生成後,咱們能夠將其保存在文件系統或者Pact-Broker(Pact提供的中間件,用來管理契約文件)中,以便後續提供者使用。
基於消費者驅動出的契約,對提供者進行驗證
在提供者端,咱們不須要寫任何驗證的相關代碼,Pact已經提供了驗證的接口,咱們只須要作好以下配置:
一、爲提供者指定契約文件的存儲源(如文件系統或者Pact-Broker)。
二、啓動提供者,運行PactVerify(Pact有Maven、Gradle或者Rake插件,提供pactVerify命令)。
三、當執行pactVerify時,Pact將按照以下步驟,自動完成對提供者的驗證:
構建Mock的消費者。
四、根據契約文件記錄的請求內容,向提供者發送請求。
五、從提供者獲取響應結果。
六、驗證提供者的響應結果與Pact契約文件定義的契約中是否一致。
傳統狀況下作集成測試須要把服務消費者和服務提供者兩個服務都啓動起來再進行測試,而Pact作契約測試時將它分紅兩步來作,每一步裏面都不須要同時啓動兩個服務。
一、測試解耦,就是服務消費與提供者解耦,甚至能夠在沒有提供者實現的狀況下開始消費者的測試。
二、一致性,經過測試保證契約與現實是一致性的。
三、測試前移,能夠在開發階段運行,並做爲CI的一部分,甚至在開發本地就能夠去作,並且能夠看到一條命令就能夠完成,便於儘早發現問題,下降解決問題的成本。
四、Pact提供的Pact Broker 能夠自動生成一個服務調用關係圖,爲團隊提供了全局的服務依賴關係圖。
五、Pact提供Pact Broker這個工具來完成契約文件管理,使用Pact Broker後,契約上傳與驗證均可以經過命令完成,且契約文件能夠制定版本。
六、使用Pact這類框架,能有效幫助團隊下降服務間的集成測試成本,儘早驗證當提供者接口被修改時,是否破壞了消費者的指望。
七、Pact目前僅支持REST HTTP 通訊,但對於RPC的通訊機制,暫不支持。
注:寫到最後,夜也深了,若是你以爲本文對你有點啓發或者做用,歡迎打賞支持一下~
若是你想全面進階測試技術,給你們推薦一個全棧測試工程師技術修煉專欄《軟件測試52講》,筆者本身也要訂閱學習,專欄內容很是不錯,值得學習!
詳細見:原文連接
新開了一個知識星球:【測試開發學苑】,在這裏不但能夠參與有趣且有意義的話題討論,還能夠獲得任何與測試和開發相關問題的解答,歡迎你們加入,共同成長。