Java基礎學習總結(118)——單元測試的必要性和重要性

一杯甜酒發表於2017-11-15
大部分程式設計師有兩個特點:一不願意寫文件和註釋,二不願意寫單測。單元測試是黑盒測試的基礎,基本的准入測試,既能驗證邏輯的準確性,又能給後續的介面重構提供基礎。總之就是『單元測試很重要』,在敏捷迭代開發過程中,開發人員往往對單元測試不夠重視,主要原因還是排期緊,比如我們團隊初期對單測的要求是所有的 dao 層都要進行單測覆蓋,到後來時間充裕才在 service 層進行單元測試的補充。controller 層的單元測試由於經常採用 mock 物件,很多人嫌繁瑣就索性直接跟前端聯調,不去管了。那為什麼要寫單元測試?單元測試能以更細的粒度,構造更多的業務場景,模擬更多的輸入行為,在此過程中保證程式行為如程式設計師所想。單元測試可以驅動重構,通過重構進而優化程式碼本身,為什麼這麼說呢?因為單元測試對於被測試程式碼是有要求的,那什麼是好的程式碼呢?援引一個我認識的架構師的觀點,好的程式碼有以下特點:可讀性。程式碼整潔有序;命名規範,見名知意(get/load, create/build), 在方法沒有好到見名知意或者有特殊業務邏輯時,加必要註釋。擴充套件性,易維護性。合理規劃變和不變(核心業務邏輯不變);抽取模組、服務、方法;NO 複製貼上效率。避免一個請求對遠端服務/資料庫重複請求可測性。避免大而全的方法,一個方法只做一件事(大方法抽取出多個可測小方法);相似的事情儘量合併成一個方法(比如 dao,sql 不要寫死,儘量一個 sql 可以做多件事情)其中可測性是單元測試對程式碼的基本要求,所以當你發現程式碼不可測試了,是時候重構了,這也是一個程式碼重構時機的判斷標準。
那麼如何寫好單元測試:單一職責,每個 case 測試一件事情,原子無歧義,失敗無需 debug;case 按照業務場景拆分,註釋保證覆蓋全面,追加刪除方便;測試的 case 間沒有依賴;case 之間無冗餘;case 乾淨。(資料庫、磁碟、程式狀態等)前後保持一致
最近負責一個複雜改動邏輯較多的迭代,對較多業務模組進行了重構,寫了很多單元測試。所以順便做個總結,單元測試是自己程式碼邏輯的檢查員,是別人閱讀你程式碼的入口,也是重構的保障

最近看 Eureka 的原始碼,看原始碼除了從任何一個函式作為入口著手外,有個很好的技巧就是從單元測試入手,本章最後來兩張圖來看下 Eureka 原始碼的單元測試,這種測試驅動的思想和做法值得我們學習。


圖1可以清晰看到 eureka server 初始化過程:初始化配置、啟動服務、建立 eureka server 載入配置,通過該入口進去可以看到 eureka 初始化的所有細節。


上圖是服務的註冊、傳送心跳(renew 續約)以及失去心跳的入口,比直接找原始碼簡單很多。

相關文章