淺談單元測試 - 如何判斷優先權

之前在淺談單元測試 - 管理篇分享了我們該怎麼將單元測試帶入團隊裡。裡面有提到:

在有時間成本的考量前提下,找出重要的業務邏輯或是高風險程式優先處理,將會非常有效益。

時間是工程師最稀缺的資源,該怎麼對 codebase 做排序,必須要事前思考。本篇文章會分享我如何判斷寫單元測試的優先權。

流程

  1. 首先先確定目標的層級為何,如 repo、服務或是產品等,確認好後再將相同層級的項目列出來。
  2. 將這些項目依照下面兩種維度來定義等級,維度的等級可以採用二分法或光譜:
    • 重要性,這個指標衡量會比較複雜,後面會再補充說明。
    • 更新頻率,可以參考歷史記錄用一個時間區間至少更新一次來介定是否頻繁,時間區間如:一個月、一季、半年、一年等。為何會參考這個指標,下面會有額外的解釋。

等級定完後,放入下面的坐標圖裡:

優先順序將會是 A -> B -> C -> D。

判斷功能的重要性

重要性的指標定義比較複雜,會依產品特性來決定,如:商業價值、影響範圍、執行頻率等來綜合評估,較難客觀地算出等級。這裡準備了幾個參考用的是非題,如果答案都是 Yes,那它可能就蠻重要的。

  1. (商業價值)此功能是否與賺錢直接相關?
  2. (影響範圍)此功能壞掉的時候,是否會有其他不相關的人關心此功能的狀況?
  3. (執行頻率)此功能是否經常被觸發執行?

為何會參考頻率指標

不管是單元測試,或是寫文件等,都有機會節省未來修改程式整體的時間,像單元測試是省下迴歸測試的時間,文件則是省下帶新人的時間。但這件事是否值得投資,該如何判斷?

有個表是長這樣子的,是一個「省下的時間」(第一欄)與「執行頻率」(表頭)的對照表。比方說第一欄的 1 秒,對照到 50 次/天,然後再算出持續五年總共可以省下多少時間。

省多久時間 / 次 50 次/天 5 次/天 1 次/天 1 次/週 1 次/月 1 次/年
1 秒 1 天 2 小時 30 分鐘 4 分鐘 1 分鐘 5 秒
5 秒 5 天 12 小時 2 小時 21 分鐘 5 分鐘 25 秒
30 秒 4 週 3 天 12 小時 2 小時 30 分鐘 2 分鐘
1 分鐘 8 週 6 天 1 天 4 小時 1 小時 5 分鐘
5 分鐘 9 月 4 週 6 天 21 小時 5 小時 25 分鐘
30 分鐘 N/A 6 月 5 週 5 天 1 天 2 小時
1 小時 N/A 10 月 2 月 10 天 2 天 5 小時
6 小時 N/A N/A N/A 2 月 2 週 1 天
1 天 N/A N/A N/A N/A 8 週 5 天

這是從網路上看到的圖轉換成表格的,但原始來源不明。

從這個表可以發現幾件事,舉幾個例子:

  1. 如果省下短短 1 分鐘,但假如一天要執行個 50 次的話,持續五年就可以省下整整 8 週的時間。
  2. 反過來說,即便一天執行個 50 次,如果只有省下 1 秒,持續五年也不過才省 1 天的時間。

這件事會對應到,假如我們想花一些成本投資設備或基礎建設,省下稀缺的時間資源,但預期成效該怎麼評估,這時就可以用這張表來呈現。另外也可以算出投資的成本效益比,也就是俗稱的 C/P 值。

比方說,原本使用 i5 CPU,想花 10 萬投資買一台最新的 M1X Macbook,跑整合測試的速度可以提升,並省下 5 分鐘的時間。但問題是,這台電腦編譯的頻率有多少?有些人的習慣是一天只跑一次整合測試,參考上面的表格,持續五年只會省下 6 天的時間,這 C/P 值明顯不是很好。

再舉個例子,原本人工做回歸測試需要花 1 小時,但改成自動化測試只要花 5 分鐘,省了超過 30 分鐘的時間,但預期會花 1 個月的時間開發。自動化測試通常一天可以執行 5 次以上,一樣參考上面的表格,持續五年就能省下超過六個月的時間,而且這個好處是團隊共享的,因此可能就會好幾倍的六個月,那投資這 1 個月的 C/P 值就會非常高。

從上面的例子可以得知,迴歸測試越頻繁的程式,針對迴歸測試改寫自動化測試的好處就越加明顯。因為單元測試也可以做為一種迴歸測試,因此才會將此指標做為主要考量因素。

小結

以上是我定義的判斷優先等級方法,不同的情境可能會有不同的需求和判斷方法,大家可以依需求建立屬於自己的優先列表。


感謝 @tedmax100@yaochangyu@jame2408 等好友提供許多寶貴的經驗。