在測試金字塔模型中,從上至下分別是UI測試、接口測試、單元測試,UI測試的運行效率低,且維護成本高;而單元測試在研發測試活動中基本是由研發同學在負責;對于測試同學來說,接口自動化測試就成為了我們提高測試效率的重要手段之一。通過接口自動化測試,我們可以快速進行業務功能冒煙測試、回歸測試等測試活動。
因此在項目研發測試過程中,各個測試團隊都會特別重視自動化測試能力的建設。隨著產品功能的不斷迭代,自動化測試用例數量的不斷增加,我們在執行自動化測試的過程中會發現自動化測試執行時失敗的噪音會變大,排查自動化失敗的用例會花掉我們大量的時間,而最終排查結果卻顯示只有一小部分用例失敗是由于代碼缺陷導致的,大部分的測試用例執行失敗是測試環境或用例本身設計不合理導致的,接下來我們就談談治理接口自動化測試穩定性問題的一些常見思路。
測試環境穩定性治理
測試環境的穩定性是接口自動化測試用例可以持續穩定執行的第一要素,完備和穩定的測試環境對持續穩定地開展各項測試活動意義重大,我們可以從以下幾個方面入手:
- 合理規劃測試開發環境使用,這里我們僅討論線下環境的dev和test環境,dev環境用于研發同學編碼部署、自測、聯調,以及基礎的功能測試,部署研發分支代碼;test環境用于測試同學執行手工測試、集成測試、自動化回歸測試,部署master分支代碼;
- 確保環境的使用權在可控范圍內,測試環境的代碼部署、配置變更、重啟等操作權限應收口在測試owner手中,由測試owner進行維護;
- 規范變更流程,服務發布、參數配置、DDL/DML等變更應該有完善的發起/審核/執行/回滾流程,不能隨意進行變更;
降低接口自動化測試用例對外依賴
很多時候我們發現接口自動化測試用例執行失敗,是由于依賴服務不穩定導致,例如我們的被測應用A的接口內部,依賴應用B的某個接口,當我們在執行自動化測試用例時,可能會由于B應用服務的不穩定而導致A應用的接口自動化測試失敗,甚至B應用服務的接口還會往下依賴C應用等,當我們的調用鏈路越長,自動化測試用例的穩定性就越差。
而降低自動化測試用例耦合性最好的方法就是通過mock組件,直接返回我們需要下游接口返回的結果,通過這種方式,我們不僅能降低對下游應用接口的依賴,還能更方便地進行一些異常場景的測試,例如超時異常或者一些不太容易構造的業務異常等場景。在單元測試或單接口測試中我們可以使用mockito等組件,而在跨微服務接口的測試場景中,我們可以通過在spring context中插入mock規則的方式,通過mock組件攔截返回我們需要的mock結果。
自動化測試用例中減少數據庫連接的使用
接口自動化測試的斷言和校驗包括兩部分:接口響應體和數據持久化。舉個例子,我們的被測接口是注冊用戶,我們的測試步驟應該是:構造調用參數 -> 發起接口調用 -> 校驗接口響應體 -> 校驗數據庫中的用戶數據持久化。通常我們會封裝一些DriverManager.getConnection()方法來實現自動化測試腳本對數據庫的操作:連接數據庫、查詢數據,然后轉換數據格式并進行數據完整性、正確性的校驗。
當然,我們通過良好的代碼規范,在數據庫操作完后,在 finnally 模塊中增加DriverManager.getConnection().createStatment().close()方法可以及時釋放數據庫連接,減緩數據庫的壓力。但是當我們并發地執行自動化測試用例時,不可避免地會建立大量的數據庫連接,同時由于部分用例中查詢的數據量過大,或者sql索引建立不規范等原因,會導致數據庫連接被長時間占用,從而影響其他測試用例的執行,甚至影響手工測試執行。
那么如何規避上述問題呢,最簡單直接且有效的方式,就是通過接口調用請求服務端的查詢接口,通過查詢接口返回的結果來判斷。仍然以上面場景為例,我們的測試步驟就變為:構造調用參數 -> 發起接口調用 -> 校驗接口響應體 -> 調用用戶查詢接口 -> 校驗用戶信息是否完整/正確。通過這也的方式,我們不僅能降低測試環境數據庫的開銷,提升測試環境穩定性,還能提升自動化測試用例的執行效率。
充分利用中間件測試方法
造成自動化測試用例運行不穩定的另一個場景,就是涉及到一些例如定時調度任務、異步消息等中間件的用例。例如測試環境異步任務5分鐘或10分鐘執行一次,那么我們就需要等到定時任務觸發后,才能進行結果校驗,這也無疑會大大降低我們自動化測試用例的執行效率和穩定性;同樣地,針對異步消息的測試場景,我們大多數時候會依賴上游或者域內其他應用投遞的異步消息,而我們想要在上游系統中去構造一個異步消息是較困難的,不僅依賴上游系統環境的穩定性,且還依賴對方功能的可靠性,當對方環境出現故障或功能有缺陷時,我們的自動化測試用例就會執行失敗。
這時候我們應該把中間件提供的一些公共測試方法好好利用起來,針對調度任務的場景,我們可以獲取到業務id,調用調度任務的執行接口,執行指定的某一條任務數據,這也既不會影響其他同學測試,也可以更快速高效地執行我們想要的動作;另外針對異步消息地場景,我們可以使用msgbroker中間件的消息mock能力,將我們需要的消息體構造出來后投遞到我們需要的消息分組或指定的消息消費服務器上,如果擔心消息亂序或者跑偏的情況,我們可以在做好消息冪等處理的前提下,進行消息重投,保證我們服務器可以接收到消息。