大家都說單測沒啥用,這是真的嗎?

2023-03-09 06:01:35

大家好,我是樹哥!

工作了快 10 年了,跟研發小夥伴聊起單測,絕大多數人的反應是 —— 單測沒啥用,寫單測就是為了應付單測覆蓋率的 KPI 指標。恰好我最近在團隊落地單測相關的內容,經過一段時間的持續迭代,我對單測的看法也從一開始的 沒啥用 到後面的 好像有點東西,再到最後的 臥槽,真牛逼!。基本上隨著單測寫得越深入,我對單測就越發重視。

為啥說單測沒啥用?

那些說單測沒啥用的小夥伴,我想大概率是不知道怎麼寫單測,沒寫過真正合格的單測,而只是用單測來湊湊單測覆蓋率的 KPI 指標。在這種情況下,單測當然沒啥用,因為它沒辦法幫你提高程式碼質量,幫你減少 bug。試想一下,如果一個東西能幫你提升需求開發質量,減少提測需求 bug 數量,那研發同學怎麼可能不願意去學習一下呢?

在我看來,單測一個很明顯的價值就是 —— 它能極大地減少你的需求 bug 數量,甚至一個 bug 都沒有! 那為啥大家都會覺得單測沒用呢?我想問題可能是多方面的,其中可能的幾個原因是:

  1. 需求不明確,邊寫程式碼邊改需求,這咋寫單測?
  2. 時間非常趕,業務程式碼都寫不完,還寫單測?
  3. 不知道咋寫單測,於是隨便寫寫,發現好像沒啥用?
  4. 沒有選擇合適的單測框架,單測程式碼寫得業務程式碼還多,這可咋整?
  5. 等等

總而言之,這一切的原因導致沒寫出合格的單測,沒辦法讓單測為他們帶來好處,於是它們對單測充滿了失望,最終就覺得單測沒用。那怎麼寫出合格的單測呢?這就是另外一個話題了,有機會我們再詳細聊聊。

單測到底有啥用?

聽我瞎扯了半天,有同學忍不住了:看你把單測吹得,那你說單測到底有啥用?

在我看來,單測除了顯著提升需求程式碼質量之外,還有下面幾個好處:

  1. 提升系統穩定性
  2. 系統更加健壯
  3. 提升程式碼編寫能力
  4. 有利於穩定迭代
  5. 有利於深入瞭解技術與業務

提升系統穩定性。 如果你每一個方法函數都經過了測試,並且其分支覆蓋率都達到了較高水平,那麼你很難寫出有問題的程式碼,因為每種情況你都考慮到了。而在後續的迭代中,由於單測用例的存在,它就可以保證修改後的程式碼不會影響到之前的業務邏輯。簡單來說,由於單測的存在,違背之前業務邏輯的程式碼無法執行通過,因此提高了系統穩定性。

系統更加健壯。 系統的健壯,其實是得通過分支覆蓋率來實現的。分支覆蓋率,其實就是每一種可能的情況你都考慮到了,那麼系統會更加健壯。舉一個很簡單的例子,有一個計算器類的除法函數,簡單的測試可能只會用正數進行測試,更進一步地可能會用負數,但是如果用 0 去測試呢?是否能成功呢?通過對分支覆蓋率的要求,使得我們考慮到更多異常情況,從而使得系統更加健壯。

提升程式碼編寫能力。 當我們開始對單測覆蓋率和分支覆蓋率有要求,並且開始寫單測程式碼之後,我們會被迫站在另一個視角去審視我們寫的程式碼。如果我們的程式碼寫得一點邏輯都沒有,那我們的單測會很難寫,那我們會忍不住去重寫它,這就間接地提升了我們的程式碼編寫能力。與程式碼邏輯類似,程式碼的結構以及設計也會影響單測的編寫,寫單測可以讓我們重新審視自己寫得程式碼,從而間接提升我們的程式碼編寫能力。

有利於穩定迭代。 如果你寫得程式碼質量很高,只有非常少的 bug,甚至一個 bug 都沒有。那麼測你需求的測試肯定很開心,因為直接一把過呀!從專案管理層面來看,如果每個人都能做到這樣的程度,那麼專案的迭代是非常穩定、並且高效的!

有利於深入瞭解技術與業務。 當我們寫單測的時候,我們必須去了解某個東西是怎麼執行的。如果你沒有了解清楚某塊業務,就開始去修改這塊業務的程式碼,那之前的單測用例會教你做人,頻頻報錯的單測資訊會讓你寸步難行。單測用例的存在讓你必須弄清楚這塊業務的邏輯,才可以寫新的業務邏輯,這間接促進了我們對於業務的瞭解。此外,我們寫單測的時候經常會進行 Stub 和 Mock,這會要求你必須弄清楚專案中用到的技術原理,不然你無法成功編寫單測程式碼,這也同樣間接促進你去了解專案中用到的技術。

單測不是銀彈

說了這麼多,可能有些小夥伴覺得我是單測的死忠粉。但我想說的是:單測也不是銀彈!

在我看來,單測只能解決一類問題,那就是 —— 你覺得你寫對了,但是你沒寫對的問題。 對於那些你本來就不知道,或者說程式碼里根本就沒寫的東西,單測是無能為力的。舉個很簡單的幾個例子:

  • 提測提了一個 bug,你排查之後發現有某個業務細節你沒考慮到,從而觸發了這個 bug。由於你本來就沒考慮到,因此程式碼裡也沒有做對應的處理,那麼單測肯定也解決不了這個問題。
  • 由於產品對需求沒有寫清楚,於是在測試解決不斷補需求細節,於是你也不斷地修修改改,於是越改 bug 越多。

除此之外,寫單測也確實是會費一些時間,特別是對於剛剛寫單測的同學來說。如果一個專案非常緊張,需求也不確定,經常邊寫程式碼邊該需求,這時候再要求單測覆蓋率,可能不太現實。

單測的適用場景

看了這麼多,知道了單測有那麼多好處,但又單測又不能包治百病,那單測到底適合在什麼場景使用呢?

在我看來,對於是否要推行單測,以及單測的要求高低,其實取決於下面幾個維度:

  1. 1. 程式碼複用率。 程式碼複用率越高,越有必要推行單測,越有必要提升單測的要求。因此這些程式碼被很多業務參照,因此其一旦有問題便會影響很多業務方,在這樣的程式碼推行單測是收益較高的。
  2. 業務變化率。 業務變化越快,越不適合用單測。如果業務變化非常快,一個單測的內容上線了沒幾天就又要修改,那麼你不僅僅需要修改業務程式碼,還需要修改單測程式碼,那就是雙倍的工作量了。
  3. 人員變化率。 人員變化率指的是某個模組負責人的變化情況。如果某個模組的負責人經常變來變去,那麼也是不太適合推行單測的。因為新負責的人需要花大量的時間去熟悉單測的內容,這會導致需求開發的時間變得非常長。
  4. 業務重要性。 越是核心的業務,越有必要推行單測,並且越有必要以高標準要求。因為核心業務的穩定性、健壯性對於公司來說肯定非常重要,而單測確實是能夠在最小單元去提升系統穩定性和系統健壯性。

上面提到的 4 個衡量維度,我們不能單一地去看待,而是要根據實際情況去綜合判斷。例如某個業務的人員變化就是很頻繁,那就一定不適合推行單測嗎?其實並不是,而是說對於人員變化非常頻繁的業務,其推行單測成本會很高。但如果這塊業務就是非常重要,但他的人員變化就是很頻繁,那強制以高標準的單測要求確實可以提高系統健壯性和系統穩定性,但是代價就是研發時間很長。如果產研團隊能夠接受這個結果,那麼這麼做就是合理的。

總的來看,是否推行單測以及推行單測的標準高低,需要我們根據上面幾個維度去綜合考量,得出一個最適合的標準!