大家好,我是樹哥!
工作了快 10 年了,跟研發小夥伴聊起單測,絕大多數人的反應是 —— 單測沒啥用,寫單測就是為了應付單測覆蓋率的 KPI 指標。恰好我最近在團隊落地單測相關的內容,經過一段時間的持續迭代,我對單測的看法也從一開始的 沒啥用
到後面的 好像有點東西
,再到最後的 臥槽,真牛逼!
。基本上隨著單測寫得越深入,我對單測就越發重視。
那些說單測沒啥用的小夥伴,我想大概率是不知道怎麼寫單測,沒寫過真正合格的單測,而只是用單測來湊湊單測覆蓋率的 KPI 指標。在這種情況下,單測當然沒啥用,因為它沒辦法幫你提高程式碼質量,幫你減少 bug。試想一下,如果一個東西能幫你提升需求開發質量,減少提測需求 bug 數量,那研發同學怎麼可能不願意去學習一下呢?
在我看來,單測一個很明顯的價值就是 —— 它能極大地減少你的需求 bug 數量,甚至一個 bug 都沒有! 那為啥大家都會覺得單測沒用呢?我想問題可能是多方面的,其中可能的幾個原因是:
總而言之,這一切的原因導致沒寫出合格的單測,沒辦法讓單測為他們帶來好處,於是它們對單測充滿了失望,最終就覺得單測沒用。那怎麼寫出合格的單測呢?這就是另外一個話題了,有機會我們再詳細聊聊。
聽我瞎扯了半天,有同學忍不住了:看你把單測吹得,那你說單測到底有啥用?
在我看來,單測除了顯著提升需求程式碼質量之外,還有下面幾個好處:
提升系統穩定性。 如果你每一個方法函數都經過了測試,並且其分支覆蓋率都達到了較高水平,那麼你很難寫出有問題的程式碼,因為每種情況你都考慮到了。而在後續的迭代中,由於單測用例的存在,它就可以保證修改後的程式碼不會影響到之前的業務邏輯。簡單來說,由於單測的存在,違背之前業務邏輯的程式碼無法執行通過,因此提高了系統穩定性。
系統更加健壯。 系統的健壯,其實是得通過分支覆蓋率來實現的。分支覆蓋率,其實就是每一種可能的情況你都考慮到了,那麼系統會更加健壯。舉一個很簡單的例子,有一個計算器類的除法函數,簡單的測試可能只會用正數進行測試,更進一步地可能會用負數,但是如果用 0 去測試呢?是否能成功呢?通過對分支覆蓋率的要求,使得我們考慮到更多異常情況,從而使得系統更加健壯。
提升程式碼編寫能力。 當我們開始對單測覆蓋率和分支覆蓋率有要求,並且開始寫單測程式碼之後,我們會被迫站在另一個視角去審視我們寫的程式碼。如果我們的程式碼寫得一點邏輯都沒有,那我們的單測會很難寫,那我們會忍不住去重寫它,這就間接地提升了我們的程式碼編寫能力。與程式碼邏輯類似,程式碼的結構以及設計也會影響單測的編寫,寫單測可以讓我們重新審視自己寫得程式碼,從而間接提升我們的程式碼編寫能力。
有利於穩定迭代。 如果你寫得程式碼質量很高,只有非常少的 bug,甚至一個 bug 都沒有。那麼測你需求的測試肯定很開心,因為直接一把過呀!從專案管理層面來看,如果每個人都能做到這樣的程度,那麼專案的迭代是非常穩定、並且高效的!
有利於深入瞭解技術與業務。 當我們寫單測的時候,我們必須去了解某個東西是怎麼執行的。如果你沒有了解清楚某塊業務,就開始去修改這塊業務的程式碼,那之前的單測用例會教你做人,頻頻報錯的單測資訊會讓你寸步難行。單測用例的存在讓你必須弄清楚這塊業務的邏輯,才可以寫新的業務邏輯,這間接促進了我們對於業務的瞭解。此外,我們寫單測的時候經常會進行 Stub 和 Mock,這會要求你必須弄清楚專案中用到的技術原理,不然你無法成功編寫單測程式碼,這也同樣間接促進你去了解專案中用到的技術。
說了這麼多,可能有些小夥伴覺得我是單測的死忠粉。但我想說的是:單測也不是銀彈!
在我看來,單測只能解決一類問題,那就是 —— 你覺得你寫對了,但是你沒寫對的問題。 對於那些你本來就不知道,或者說程式碼里根本就沒寫的東西,單測是無能為力的。舉個很簡單的幾個例子:
除此之外,寫單測也確實是會費一些時間,特別是對於剛剛寫單測的同學來說。如果一個專案非常緊張,需求也不確定,經常邊寫程式碼邊該需求,這時候再要求單測覆蓋率,可能不太現實。
看了這麼多,知道了單測有那麼多好處,但又單測又不能包治百病,那單測到底適合在什麼場景使用呢?
在我看來,對於是否要推行單測,以及單測的要求高低,其實取決於下面幾個維度:
上面提到的 4 個衡量維度,我們不能單一地去看待,而是要根據實際情況去綜合判斷。例如某個業務的人員變化就是很頻繁,那就一定不適合推行單測嗎?其實並不是,而是說對於人員變化非常頻繁的業務,其推行單測成本會很高。但如果這塊業務就是非常重要,但他的人員變化就是很頻繁,那強制以高標準的單測要求確實可以提高系統健壯性和系統穩定性,但是代價就是研發時間很長。如果產研團隊能夠接受這個結果,那麼這麼做就是合理的。
總的來看,是否推行單測以及推行單測的標準高低,需要我們根據上面幾個維度去綜合考量,得出一個最適合的標準!