簡介: 在所有的開發測試中,介面測試是必不可少的一項。有效且覆蓋完整的介面測試,不僅能保障新功能的開發質量,還能讓開發在修改功能邏輯的時候有迴歸的能力,同時也是能優雅地進行重構的前提。編寫介面測試要遵守哪些原則?測試程式碼的結構應該是什麼樣的?介面測試有哪些實踐技巧?本文分享作者在介面測試上的實踐總結。
一線開發同學,可能都或多或少地造成過線上bug甚至故障;也會遇到這樣的場景,某同學在開發某功能的時候重構了程式碼,造成了線上bug或者故障;在開發某個功能時,發現需要修改公共邏輯,害怕影響到其他功能,非常不雅觀地複製程式碼,重新寫套單獨邏輯來支援。
上面這些情況,都包含了一個關鍵的問題,無論是功能開發還是邏輯重構,如何來保障程式碼開發的質量。保障的手段,每個人都知道,就是測試。首先是新功能測試,保障新功能邏輯正確;其次是迴歸測試,保障原有業務功能邏輯正確。測試的方式,一般是兩種,人工測試和自動化測試。隨著測試技術和工具的持續發展,人工測試比例逐步降低,被自動化測試逐步替代。自動化測試是可持續和可重複的,甚至是可AI化的。
一、 測試分層測試也是分層的,如下圖所示:
在一個系統內,自動化測試一般分單元測試、模組測試和介面測試。
單元測試
目前我的應用程式碼基本都是基於spring框架面向介面這種程式設計模式,單元測試已被弱化。單元測試的要求基本上是單個類單個方法的測試,在我們當前模式下,編寫成本太高。當然,如果是一個工具或者一段比較內聚而又複雜的邏輯(例如演算法邏輯),還是應該使用單元測試來保障邏輯的正確性。
模組測試
在系統比較大、模組比較多的情況下,可以建立模組測試層,保障各模組功能的正確性。不過當前的系統發展趨勢是微服務架構,因此模組測試層並非十分必要,可以透過介面測試層來覆蓋。
介面測試
個人覺得準確來說應該叫入口測試,這一層,是從系統入口出發進行整合測試。應用入口通常是HSF(一個分散式RPC服務框架)服務,訊息,定時任務。
作為開發,測試手段千萬條,介面測試不可少。在我們應用的介面測試有效且覆蓋完整的情況下,不僅能保障我們新功能的開發質量,還能讓我們在修改功能邏輯的時候有迴歸的能力,同時這也是我們做程式碼重構的前提。同時,易測性也是程式碼結構合理的一個指標,如果發現一段程式碼編寫測試指令碼困難或者無法測試,那就說明當前程式碼結構不合理需要重構。接下來,我將主要談一談介面測試的有效性。
二、 測試原則基礎原則:
自動化:介面測試是非互動式的自動化執行,不需要人參與。獨立性:介面測試之間不應該相互依賴。可重複:介面測試可重複執行,不受環境影響。介面測試遵守BCDE原則,保障介面交付質量。 Border:邊界測試。 Correct:正確的輸入,正確的預期輸出。 Design:按照需求和設計文件編寫測試邏輯。 Error:錯誤輸入,預期輸出。資料準備:資料準備透過系統服務進行,不能透過直接插入db方式。可測性:對於不可測的程式碼需要進行重構成合理的結構。覆蓋性:介面測試需要覆蓋所有UC,同時代碼覆蓋率和分支覆蓋率應達到一定標準,新增程式碼必須被覆蓋。持續性:如果程式碼修改導致已有介面測試執行失敗,必須修復程式碼問題或者測試程式碼邏輯。時間要求:介面測試應該在專案釋出之前完成,不應放到專案釋出之後補充。以上的基本原則應適用於所有層的自動化測試用例,在編寫介面測試時,除了上面這些原則,還有其他原則需要遵守,先看一張圖:
從系統角度來分析入口呼叫,以HSF服務為例:
外圍系統呼叫由我們系統提供的服務。系統執行了一堆程式碼邏輯,其中包含有分支邏輯。系統執行過程中依賴外部HSF服務,進行了呼叫,並得到了返回值。系統執行過程中依賴DB查詢或者落地了資料,依賴快取查詢或者落地了資料。系統執行過程中對外發送了訊息。給上游系統返回HSF執行結果。有效介面測試的關鍵原則是要覆蓋所有入口,mock所有依賴,校驗執行過程中所留下的痕跡,總結如下:
入口覆蓋:介面測試用例必須覆蓋HSF服務入口、訊息入口、定時任務入口。依賴mock:在基本原則中,有可重複這個原則,即介面測試不能受環境依賴,需要mock掉對外依賴。但對於db依賴,不建議完全mock掉,一方面mock成本高,另外可能覆蓋不到sql和表約束邏輯。校驗完整:有效的介面測試,應該具備完整的校驗,沒有校驗的介面測試是沒有意義的。只要執行過程中,留下的痕跡對業務有影響,都要進行完整校驗,方能保障介面測試的有效性。 HSF介面返回值校驗:按照場景和介面約定進行HSF返回引數校驗。 DB校驗:校驗落地資料的正確性。 快取校驗:校驗存入快取中資料的正確性。 HSF依賴入參校驗:透過mock工具獲得依賴HSF呼叫的入參,進行入參校驗。 訊息校驗:透過mock工具獲得傳送的訊息物件,進行訊息體校驗。三 、測試程式碼結構在編寫測試程式碼的時候,也應跟寫業務程式碼一樣,考慮程式碼的可讀、可擴充套件、可複用性。同時也可以根據系統的業務特性,在測試框架的基礎上封裝適合當前系統的測試元件,提高測試程式碼編寫效率,規範測試程式碼結構。
一個介面的測試程式碼,大概的結構如下:
1 、測試準備
依賴資料準備
很多時候,我們的測試有資料依賴,可能是配置資料,也有可能是業務資料(例如退款需要依賴支付資料)。
配置資料:可以透過定義配置檔案來初始化配置。業務資料:這類資料,禁止透過直接插入資料方式產生,而是應透過呼叫業務服務產生。依賴mock
對於外部依賴,需要對被依賴的服務進行mock,避免真實呼叫。
介面測試入參準備
準備介面方面的入參。
2 、測試執行
呼叫介面方法,執行業務邏輯。
3、 測試校驗
返回引數校驗:校驗介面的返回引數。DB:校驗DB落地資料。快取資料校驗:校驗落地到快取中的資料。訊息校驗:校驗對外發送的訊息物件。對外HSF呼叫校驗:校驗對外HSF呼叫的入參。四 、實踐技巧1 、執行效率
對於介面測試,執行效率是不得不關注的一個點,若一個介面測試執行3分鐘以上才能看到結果,會大大降低開發同學編寫介面測試的熱情。對於測試執行效率提高,建議的方案為:
最小化啟動測試上下文,例如spring boot的應用,啟動spring就可以了使用記憶體資料庫,例如h2將中介軟體依賴mock掉2、測試框架選擇
對於測試框架,建議選擇基於testng,能夠提供透過配置檔案做資料準備的測試框架。如果找不到合適的,可以自己基於testng進行封裝。
3、 介面測試覆蓋度
場景的完整性影響著測試用例的覆蓋度,一方面需要開發同學基於業務場景的輸入和測試經驗枚舉出正常和異常情況,另一方面介面方法也有一些固定需要測試的點,例如冪等測試,邊界值測試,引數不正確測試等等。
同時也要透過覆蓋率工具檢視介面未覆蓋的程式碼或分支邏輯,進行針對性的場景覆蓋測試。根據我的經驗,分支完整覆蓋非常重要,特別是異常的分支。
五 、總結要保障系統線上執行穩定,質量保障手段必不可少。雖然現在有很多自動化的保障手段,但介面測試依然是最基本的和最重要的保障手段之一。如能做到持續保障介面測試覆蓋度和有效性,很大程度上會降低線上bug的產生,開發同學也會更有積極性去重構程式碼。