在微服務架構下,將測試分為單元測試、集成測試、組件測試、端到端測試。
單元測試
即對最小可測試單元的測試。作者認為通常是面向類或者一組類的,但是在常見的單元測試講解中,通常將“單元”定義為方法級別。與常見的單元測試觀點相同,作者建議單元測試僅僅測試被測單元的邏輯,對於被測單元調用的其他方法應該通過mock的方式進行模擬。
集成測試
在很長的時間內,我將集成測試理解為服務化架構下針對某支接口的測試(面向某個服務,不面向網關)。事實上,集成測試解決的問題更多是單元測試無法解決的問題,同時,集成測試的執行不應依賴於服務的啟動,因為服務啟動的代價非常昂貴、並且通過啟動服務的方式進行測試不夠靈活。
一直以來沒有很好測試思路的持久層測試,就可以通過集成測試解決。在測試前需要准備一套可用的數據存儲環境(數據庫或者各種分布式緩存),通過Junit等組件完成數據層的持久測試,在測試完成后要注意將數據恢復。
對於服務的集成測試則可以通過契約測試完成。建議的契約測試假設存在兩種角色:消費者Consumer與提供者Provider. 契約測試可以很好地解決這兩種角色在服務層面的集成測試問題(作為Consumer,需要測試調用Provider服務並正確處理返回的過程;作為Provider需要測試正確響應Consumer調用的邏輯。總的來看都是被測對象與服務外部產生關系的測試。)流程如下:
a. 消費者按照api定義編寫契約測試案例,並提交至提供者源碼庫
b. 服務提供方利用消費者編寫的契約測試案例生成測試代碼並對編寫的服務進行測試
c. 服務提供方將經過測試的契約通過maven或其他工具發布
d. 消費者采用服務提供方發布的契約進行測試
事實上,在測試相關的兩章中,書中所列舉的例子並沒有完整實現全部流程。以Spring Cloud Contract為例的例子更多是上述步驟中a\b\d步驟的時間,並沒有服務提供方反向發布驗證過契約的過程。
不論如何,這里消費者驅動的契約測試的核心思想在於,當服務提供方發布接口之后,由消費者按照理解編寫契約(測試案例),然后服務提供方按照該契約生成測試代碼來測試接口。這里關鍵在於由消費者按照理解編寫契約,事實上完成了雙方對於同一個接口定義的溝通(假設提供方在收到契約后發現,消費者理解有誤還可以進一步溝通,或者采用上述步驟中的c,來實現反饋)。而假設通過傳統的擋板方式,雖然消費者按照自己的理解進行了自己的測試,但是並不能保證自己的理解是服務提供方想要表達的意思。
此外,對於類似異步通信、通過發布\訂閱模式等與應用外部組件或系統通信的代碼,也可以采用類似的方案進行契約測試。
組件測試
這里所說的組件測試,即對某支接口進行驗收測試。書中建議采用各類自動化的方式執行組件測試,結合目前的開發實際,可以采用如Jmeter等工具實現組件測試。注意這里在測試過程中,對於持久層或者kafka等通信組件,需要具備一套支持組件測試的環境,而對於依賴的其他服務,則可以采用契約測試中經過驗證的擋板來進行模擬。
端到端測試
端到端測試即對待測功能在各服務、組件完全正常運行的情況進行測試,這里更類似於功能測試或者UAT測試。實際上,作者建議,在經過完善的單元、集成、組件測試后,端到端測試應該是少量的案例並且應該是自動化的。
總之,要實現一套好微服務架構風格應用體系,做好上述測試過程,並將各個測試環節自動化是必不可少的。借用作者的一句話,將應用推向單體深淵的最快途徑就是不做自動化測試。