「沒時間寫測試」是真的嗎#

許多開發者在被問到是否撰寫單元測試(Unit Test)時,最常見的回答是「我知道測試很重要,但我們真的沒時間」。這句話聽起來合情合理,但仔細想想就會發現它有些站不住腳。如果開發者沒有測試,又怎麼確認自己寫出來的功能是對的?怎麼知道這次的修改沒有破壞既有功能?又憑什麼說得出「我做完了」這四個字?

「我們有 QA 啊」的迷思#

很多團隊把品質保障完全交給 QA。試著想像一個情境:RD 只負責開發,QA 只負責測試。對 QA 而言,找出愈多 bug 才能突顯自己的價值,所以 bug 愈多愈好;對 RD 而言,需求一進來就趕緊寫完送出,反正後面還有 QA 把關。

這套運作方式表面上分工明確,實際上卻產生了一個荒謬的結果:團隊裡沒有任何人有動機去「避免 bug 產生」。久而久之,整體的品質自然會走下坡。

品質不該是被取捨的選項#

軟體管理常被簡化為「時間、成本、品質三選二」。然而當品質一旦犧牲,使用者的信任也會一併消失,這時不論時程多快、預算多省,都失去了意義。

合理的做法應該是:先把品質守在某個門檻之上,再從時間與成本之間做取捨。為什麼說「門檻之上」而不是「絕對完美」?因為沒有 bug 的程式並不存在,差別只在於 bug 是多是少、是否容易發現、是否容易修正。而這些,正是測試能夠幫忙的地方。

寫程式比較像科學還是數學#

數學追求的是「證明」,藉由邏輯推演讓一件事 100% 為真;科學追求的則是「實驗」,提出假說後反覆重現現象,當實驗在無數次中都未被推翻,我們便相信這個假說是對的。

Uncle Bob 曾說過,電腦科學比較貼近科學而非數學:要證明一段程式碼絕對正確的成本太高,幾乎做不到;但我們可以透過實驗反覆驗證它,當次數足夠多時,大家就有理由相信它是對的。

這裡的「實驗」,就是測試。

當 CI/CD 儀表板顯示某段程式碼跑過無數次測試從未失敗,老闆才有理由相信這段程式是可靠的。

測試必須自動化#

測試的種類眾多,而最基本、最單純的,就是單元測試。Martin Fowler(馬丁·福勒)在比較單元測試與整合測試(Integration Test)時提出的看法是:能夠獨立於其他服務或元件運行的測試,就屬於單元測試,至於背後是否使用 Mock 或 Stub 等技巧並非關鍵。單元測試關注「自己的功能跑起來如何」,整合測試則關注「自己的功能與其他元件合作起來如何」。

順著這個定義延伸,單元測試其實只在做一件事:

驗證自己手上寫的程式,跑起來時的表現,是否與腦中想像的一致。

如果每位開發者都能在程式旁附上佐證正確性的單元測試,現代的 CI/CD 工具就能隨時觸發、自動回報結果,效率相當驚人。剩下唯一會擋路的,就是「你寫測試的速度有多快」。Uncle Bob 的另一句名言可以作為註腳:要把事情做快,唯一的方法就是把它做好。

系列內容預告#

整個系列會圍繞單元測試展開,涵蓋以下主題:

  • 單元測試的基本概念
  • 單元測試與依賴
  • 單元測試的進階應用
  • 單元測試與重構
  • 測試驅動開發(TDD)
  • 單元測試與 Clean Architecture
  • 單元測試與流程管理

不難發現,許多軟體工程實踐其實都建立在單元測試之上。一旦掌握了訣竅,寫測試非但不會拖慢進度,反而會變成開發加速器。屆時想寫測試,就再也不必等老闆批准多給時間了。

原文出處#

  • 原書/iThome:https://ithelp.ithome.com.tw/articles/10258902