作者:京東零售 王雷
單元測試
概念
單元測試是用來對一個模組、一個函式或者一個類來進行正確性檢驗的測試工作。單元測試是一種白盒測試技術,一般都是由開發人員在編碼階段完成,目的就是驗證軟體程式碼中的每個單元(方法或類等)是否符合預期,即儘早在儘量小的範圍內暴露問題。
快速迭代的開發工作中如何提高程式碼質量一直是團隊痛點,特別是沒有測試支援的開發團隊。合理的使用單元測試,並關注單元測試透過率、程式碼覆蓋率可以有效提高程式碼質量。
雲原生引擎服務,實踐了單元測試,並在研發自測、預發、上線等階段實施了相應的策略。在一定程度上提高了程式碼的質量。
單元測試的目的
單元測試的目的在於發現各模組內部可能存在的各種錯誤,主要包括以下幾個方面:
(1) 驗證程式碼是與設計相符合的。
(2) 發現設計和需求中存在的錯誤。
(3) 發現在編碼過程中引入的錯誤。
在開發階段儘可能發現程式碼中的問題;在預發整合階段儘可能發現各個業務程式碼之間的問題;在上線階段做最後的確認保證上線程式碼質量。
單元測試除了能夠在較早階段識別軟體中的錯誤,它還有如下價值。
•反饋速度快:單元測試通常以自動化形式執行,執行速度非常快,可以快速反饋結果,跟持續整合結合起來,形成有效的反饋環。
•重構的有力保障:系統需要大規模重構時,單測可以確保對已有邏輯的相容,如果單元測試都透過,基本上可以保證重構沒有破壞原來程式碼邏輯的正確性。
•使更熟悉程式碼:寫單元測試的過程本身就是一個審視程式碼的過程,可以發現一些設計上的問題(程式碼設計的不可測試)、程式碼編寫方面的問題(邊界條件的處理不當)等。
雲原生引擎單測實踐
整體單測率
引擎在進行開發過程中,會重點關注核心模組程式碼和底層程式碼,針對重要的業務邏輯程式碼,通用元件類等,涉及到重要的功能開發,對應的每一個方法我們都要編寫對應的單元測試程式碼。在提交程式碼之前,在本地進行單測迴歸,跑通單測之後,提交程式碼,分支合併。
單元測試重點
引擎的單測重點主要體現在以下五個方面
1、輸入輸出測試
這裡主要是針對資料的輸入和輸出進行測試。
- 呼叫所測模組時的輸入引數與模組的形式引數在個數、屬性、順序上是否匹配。
- 所測模組呼叫子模組時,它輸入給子模組的引數與子模組中的形式引數在個數、屬性、順序上是否匹配。
- 是否修改了只用作輸入的形式引數。
2、路徑測試
在單元測試中,最主要的測試是針對路徑的測試;測試用例必須能夠發現由於計算錯誤、不正確的判定或不正常的控制流而產生的錯誤。
常見的錯誤有:誤解的或不正確的算術優先順序,混合模式的運算,錯誤的初始化,精確度不夠精確和表示式的不正確符號表示。
3、出錯處理
比較完善的單元設計要求能預見出錯的條件,並設定適當的出錯處理,以便在程式出錯時,能對出錯程式重新做安排,保證其邏輯上的正確性。
4、邊界條件
主要測試方法對迴圈條件,控制條件,資料流等臨界值的處理情況
比如針對一個方法中的不同分支進行單測的編寫
5、區域性資料結構
在模組工作過程中,必須測試模組內部的資料能否保持完整性,包括內部資料的內容、形式及相互關係不發生錯誤。
對於區域性資料結構,應該在單元測試中注意發現以下幾類錯誤:
1)不正確的或不一致的型別說明
2)錯誤的初始化或預設值
3)錯誤的變數名,如拼寫錯誤或書寫錯誤
4)下溢、上溢或者地址錯誤
最佳實踐
如何寫好單測
1.程式碼設計:程式碼設計上要低耦合、可測試
2.度量指標:合理的單元測試用例數量以及合理的覆蓋率
3.使用場景:要融入軟體開發中,在開發過程中經常執行
4.測試目標:要專注於程式碼中重要的邏輯
5.保證獨立性:使用mock方式放置依賴系統對單元測試結果的影響
6.用例粒度:單元測試用例應該是對單獨的功能的有意義的描述,透過用例可以瞭解改功能的邏輯
持續整合、持續卡點
程式碼自測透過後提交MR讓團隊成員進行review,當review透過時我們會透過webhook觸發預發部署流水線執行單元測試和部署
上線前檢查
當程式碼驗收透過後,進行線上部署時再次跑單元測試確保上線程式碼質量,不達標將不能部署