這篇來聊聊測試的規模、邊界,以及它們之間應有的比例。
測試金字塔#
談單元測試(Unit Test)就一定會提到 Mike Cohn 在書中提出的「測試金字塔」(Test Pyramid)。Mike Cohn 認為,一個健康的系統可以包含各種類型的測試,但單元測試應該佔最大比重,而整合度最高、貼近 UI 的測試應該數量最少。
從速度的角度看其實很合理:
- 單元測試執行速度快、覆蓋範圍小,可以在最短時間內驗證最多功能,也容易新增與修改。
- UI 本身常常被調整,測試成本又高。如果太多測試建立在 UI 上,動輒得咎,可能只是為了一個「美觀調整」,就花掉一大筆修改測試的成本,因小失大。
單元測試與整合測試#
整合測試(Integration Test)的定義到底是什麼?跟單元測試的界線又在哪?這個問題其實連 Martin Fowler(馬丁·福勒)等大師也經常在討論。Martin Fowler 部落格上 Ham Vocke 撰寫的文章建議,從 Mike Cohn 的測試金字塔中,最該記住的是兩件事:
- 撰寫不同顆粒度的測試
- 越高階的測試,數量應越少
也就是說,重點是「金字塔的形狀」:低階測試多一點、高階測試少一點。寫足夠多的小而快的單元測試,再寫一些較粗顆粒的測試,最後配上極少量的端到端測試。要避免的反模式是「測試甜筒」,意指過度倚賴高階測試而單元測試極少的情況。至於各層的命名與精確界線,反而沒那麼關鍵。
把握好金字塔的「形狀」,比糾結各層名稱與定義來得實用。低階測試多、高階測試少,並避開測試甜筒的反模式。
個人的取捨觀點#
筆者個人並不喜歡做太多的 UI 測試或跨系統的整合測試。確實,這些測試一開始較好寫,藉由現成框架甚至可以不寫程式就達到一定保護力。但其實裡面有不少問題,本來在開發階段靠單元測試就能發現,而在單元測試階段抓到問題,修復成本會便宜很多。
此外,單元測試本身就是功能的一部分。當單元測試品質夠好,對功能的信心自然也會跟著建立起來,這時較高階的測試就不需要這麼多。也有論述認為,在這個前提下,較高階的測試其實只測 Happy Path 就足夠了。
最後一個重點是「易修改性」。單元測試牽涉的範圍小,需求一變動,調整單元測試也比較靈活。寫測試其實跟寫程式一樣,不必追求需求改動時「完全不用改測試」,做到「改動幅度不會太大、跑測試不要太久」就很好了。
原文出處#
- 原書/iThome:https://ithelp.ithome.com.tw/articles/10260058