單元測試的實踐與思考

之前一直有一個想法:將測試過程的每個重要環節都進行拆解,然後詳細說明這個環節重點要做的事情,爲什麼要做這些事,以及注意事項。

在星球羣裏和幾位同學聊到了這個事情,有同學提議可否將單元測試環節加進來,斟酌一番,覺得還是很有必要的,就有了今天的這篇文章。

這篇文章,我會聊聊我對於單元測試的思考,以及些許實踐。

 

軟件研發測試的交付模型

軟件從需求出現到最後的線上發佈,大致要經歷如下幾個階段:

廣義上來說,在需求提出的時候,測試就需要介入開展相關的可測性評估。但狹義上來看,正式的測試活動開展(執行測試用例),一般是從單元測試環節開始的。

提到單元測試,大家可能首先想到的是單元測試框架,Sonar,測試的粒度要精確到方法、代碼行甚至函數級別。

見過很多同學聊單元測試,都在瘋狂追求代碼覆蓋率,好像代碼覆蓋率的指標越好看,最終的交付質量就一定會越好一樣。但真的是這樣嗎?未必!

 

單元測試要解決什麼問題

前面我寫過單元測試的一些實踐方法(見文章《測試需要做單元測試嗎?》),這篇文章其實陷入了具體的技術細節中,即單元測試到底要怎麼落地,落地執行的細節如何。

寫下這篇文章的時候,我重新覆盤了自己做測試工作以來在單元測試方面的實踐過程,發現自己好像走進了一個技術的狹窄暗巷:太過於追求技術怎麼實踐落地,忽略了做單元測試的原因,以及做單元測試的背景。

從純技術的角度出發,單元測試的粒度確實應該精確到每一個最小模塊,即一個方法或函數。

但做測試工作的畢竟是軟件工程師,從工程師的角度出發,在我看來單元測試應該考慮的是如何保證自己負責的部分(一個應用服務或者該應用服務中的某些功能模塊甚至接口)達到質量要求。

簡單來說,保證自己負責的部分技術設計和交付產物達標,也是單元測試的範疇

回想一下,在開發階段,研發同學都會進行本地自測,驗證自己實現的功能是否符合預期。

很多時候由於上下游依賴的關係,沒辦法進行聯調驗證,因此爲了避免外部影響,常見的解決思路就是直接return,或者mock(關於mock,可以參考我前面的文章《研發提效利器:聊聊mock服務化》)。

因爲要保證自己負責部分達到質量要求,自己負責部分的最小粒度是由很多個方法函數構成,因此纔有了單元測試框架、代碼覆蓋率等一系列事物的出現。

單純追求單元測試覆蓋率並不一定能提高質量,但不做單元測試,後期的測試活動開展要面臨的風險和壓力一定會上升。

一般在小公司,單元測試由研發自己負責,測試更多的是制定流程規範和提供用例,以及質量度量。當每次迭代單元測試覆蓋率到達要求時,纔會開展冒煙測試,確保整體交付到測試工程師手中的代碼達到一定質量要求,滿足可測性標準。

單元測試要解決的問題,就是確保每個階段每個人負責的最小模塊的質量,滿足流轉到下一環節的標準。

風險和缺陷越早發現修復,後面的發現和修復成本纔會越來越低,這樣才能整體上提高整個技術團隊的交付效率和交付質量

 

單元測試的實踐注意事項

在具體的實踐中,單元測試落地的最大挑戰,主要有如下幾項:

  • 測試用例:應該確保先設計單元測試用例,再編寫實現測試用例功能的代碼,即TDD(測試驅動開發);
  • 隔離依賴:執行單元測試時應確保被測單元的獨立完整性,避免依賴項對結果的影響,常用的方法是mock;
  • 測試數據:提前準備單元測試所需的數據,包括正常數據和異常數據,以充分驗證代碼在各種場景下的正確性;
  • 測試順序:應該根據調用關係合理安排測試用例的執行順序,確保各單元之間的互相依賴關係得到正確的處理;
  • 測試效率:落地單元測試之前就應該考慮將單元測試的執行納入CICD流水線中,以便能夠及時發現和修復問題;
  • 異常處理:使用正確合理的斷言來驗證代碼的執行結果是否符合預期,同時考慮錯誤場景和可能出現的異常情況;
  • 維護成本:除了跟隨迭代及時更新測試用例,還應該爲測試用例和代碼添加適當的文檔註釋,便於其他人理解維護;

最後,則是大家所熟知的測試覆蓋率。提高覆蓋率是爲了儘可能多地覆蓋代碼中的語句、分支和條件,以確保代碼的各個部分都得到了充分的測試。

但覆蓋率指標僅可以作爲一個參考值,輔助我們對單元測試執行的結果進行評估,而非一切唯指標論。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章