測試覆蓋率

2012 年 4 月 17 日

不時會聽到有人詢問他們應該追求多少測試覆蓋率(也稱為程式碼覆蓋率),或自豪地說明他們的覆蓋率。此類說法都錯失重點。測試覆蓋率是找出程式碼庫中未測試部分的有用工具。測試覆蓋率作為數值說明測試品質的用處不大。

讓我們先看看第二個說法。我聽過一些地方可能會說「覆蓋率低於 87% 不能進入生產」。我聽過一些人說你應該使用 TDD,而且必須達到 100% 覆蓋率。一位智者曾經說過

我預期有很高的覆蓋率。有時經理會要求。這之間有微妙的差別。

-- 布萊恩·馬里克

如果你將某個覆蓋率設定為目標,人們就會試著達成它。問題是,用低品質的測試很容易達到高覆蓋率。最荒謬的程度就是 AssertionFreeTesting。但即使沒有它,你還是會得到許多測試,尋找很少出錯的事情,讓你無法專注於測試真正重要的事情。

與程式設計的大多數面向一樣,測試需要周到。TDD 是非常有用的工具,但絕對不是足夠的,有助於你取得良好的測試。如果你周到且妥善地進行測試,我預期覆蓋率百分比會在 80% 或 90% 以上。我對 100% 之類的數字會感到懷疑,這會讓人覺得有人寫測試只是為了讓覆蓋率數字好看,而不是思考他們在做什麼。

當然,人們關注覆蓋率數字的原因是因為他們想知道自己的測試是否足夠。低覆蓋率數字,例如低於一半,肯定是個問題的徵兆。但高數字並不一定代表什麼,而且會導致助長無知的儀表板。測試的充足性比覆蓋率所能回答的複雜得多。如果符合以下條件,我會說你的測試已經足夠了

  • 你很少遇到會逃逸到生產環境的錯誤,而且
  • 你很少猶豫是否要變更某些程式碼,因為害怕會導致生產錯誤。

你會不會測試過度?當然會。如果你可以在仍然有足夠測試的情況下移除測試,就表示你測試過度了。但這很難察覺。測試過度的其中一個徵兆是你的測試會拖慢你的速度。如果程式碼的簡單變更會導致測試過度變長,這表示測試有問題。這可能不是因為你測試了太多東西,而是因為你的測試有重複。

有些人認為如果測試執行時間過長,就表示測試過多。我對這個論點不太認同。你隨時可以將慢速測試移到部署管線的後續階段,甚至將它們從管線中移除並定期執行。執行這些動作會延遲這些測試的回饋,但這是建置時間與測試信心的權衡取捨的一部分。

那麼,覆蓋率分析的價值是什麼呢?它能幫助你找出程式碼中哪些部分沒有經過測試。[1]不時執行覆蓋率工具並檢視這些未測試的程式碼部分是值得的。它們會讓你擔心它們沒有經過測試嗎?

如果你的測試套件的一部分以覆蓋率可以偵測到的方式薄弱,它也可能以覆蓋率無法偵測到的方式薄弱。

-- 布萊恩·馬里克

進一步閱讀

Brian Marick 有一篇關於程式碼覆蓋率誤用的精彩文章。而且值得一讀Testivus 的簡潔評論

註解

1: 這裡的「你」是指撰寫測試的人。覆蓋率對管理層來說價值不大,因為你需要技術背景才能了解測試是否良好,或者未覆蓋的程式碼是否是個問題。