業界認為應該讓契約測試來替代集成測試。認為你寫的2-5%的集成測試和單元測試有重復,或者和其它地方的集成測試存在重復,而且當集成測試失敗時,你也不知道發生了什么,不能及時準確定位問題。
一、什么是契約測試
微服務要求有低耦合、高內聚的邊界,通常我們使用 DDD 的限界上下文作為微服務邊界;而契約測試則是針對這個邊界的測試。契約測試是驗證服務的Provider是否按照期望的方式與服務的Consumer進行交互,簡單的說是Consumer與Provider兩者之間的集成。而Contract即合同、契約,就是Provider與Consumer的交互方式。
契約測試通常是基于Consumer驅動的(Consumer Driven Contracts,基于Consumer驅動的契約測試工具有PACT)。基于Consumer驅動的契約測試分兩個階段:1)Consumer生成契約,開發者在Consumer端寫測試時Mock掉Provider,運行測試生成契約文件;2)Provider驗證契約,開發者拿契約文件直接在Provider端運行測試進行驗證。
二、契約測試的特點
1)開發人員編寫,采用Mock機制,開發本地就可以運行,沒有真實調用,運行快,毫秒級修復反饋周期短;2)Provider與Consumer兩兩之間的驗證,容易定位問題,而且與底層測試或其它契約之間沒有重復;3)不需要部署真實的集成環境,穩定且成功率高;4)溝通成本低。(比如一個Consumer端的加入導致服務端API修改,服務端開發人員不必跑去找所有其它Consumer端開發人員溝通確認是否會被影響,直接運行契約測試就能知道結果。
三、擴展
1)還有一個概念叫做design by contract,它規定軟件設計人員應為軟件組件定義正式、精確和可驗證的接口規范,該規范應使用前提條件、后置條件和不變式來擴展抽象數據類型的普通定義。
2)霍爾邏輯中,霍爾三元組對理解程序更友好;P和Q是斷言,C是命令?。P叫做前置條件,Q叫做后置條件。霍爾三元組簡單理解為:只要P在C執行前的狀態下成立,則在執行之后Q也成立。
{P} C {Q}
3)聯想到solid原則的里氏替換原則,子類不應該破壞父類定下來的契約。當你發現一個子類沒有辦法完全替換其父類且并不改變原有的assertion的時候, 你就不該讓它們有繼承關系.?
四、集成測試
端到端集成測試(簡稱集成測試)是指系統集成后的自動化測試,是系統或模塊真實組裝后運行的測試。很多團隊用UI端到端來測系統集成后的行為,這類工具很多,比如有Selenium webdriver等。端到端的集成測試反饋與修復的周期比較長、運行速度慢,測試運行不穩定,有時隨機失敗,維護成本也很高。它不像單元測試,單元測試測具體一個方法或API,定位準確,采用Mock機制,運行速度非常快(毫秒級),又是開發人員在本地執行,反饋修復及時,成本較低。
集成測試的特點:1)真實安裝后測試,測試更接近真實使用情況;2)可見性強,容易理解;(比如:看一遍運行關鍵業務的集成測試,業務人員或客戶會覺得很放心。也可以替代驗收測試);3)模塊真實調用,測試運行慢,秒級別或分鐘級別,反饋與修復的周期慢,成本高;4)問題定位難,多個子模塊組合安裝后的測試,很難定位是哪個模塊出的問題;5)真實的安裝或環境搭建,不穩定,容易導致測試隨機失敗;6)溝通成本高,需要不同模塊團隊間的協調工作;7)與底層測試或集成測試會有重復,集成測試中有的路徑已經被單元測試覆蓋。