Skip to content

如何為你的 code 加測試?

了解測試策略

🧩 TDD (Test-Driven Development):

一般在導入測試時,會提倡使用TDD方式來進行,也就是「先寫測試、再開發」,由測試驅動程式結構設計,可以大幅避免寫出可測試性低的程式碼,其主要的概念為 Red => Green => Refactor,在每個功能重複執行該流程,以完成開發。

  • Red 階段: 先寫一個測試並執行,此時測試並不會通過,因為尚未進行任何開發(沒有程式碼可以被測試),但該階段可以讓開發者想清楚該功能的目的。
  • Green 階段: 依據測試寫出至少能通過測試的程式碼,並執行測試,此時測試會通過,但程式碼尚未非常完善,僅能符合測試的條件。
  • Refactor 階段: 重構上一步的程式碼,補充細節處理、提升可讀性等等,使程式碼更完整。

優點:

  • 測試提供保護網,讓開發者更有信心進行重構
  • 長期可降低除錯與修復成本
  • 減少 over-engineering,先思考行為再寫實作 (避免寫太多暫時不需要的功能,專注於當下需求)
  • 提升程式碼可測性與模組化程度,自動建立最小可測單元 (減少耦合)

挑戰:

  • 初期學習曲線較高
  • 不適合快速 prototyping
  • 對需求模糊、變動頻繁的功能會增加反覆改動成本

適用情境:

  • 需求明確、邏輯明確的功能(例如:演算法、資料驗證、表單流程)
  • 關鍵業務邏輯(如:交易計算、權限驗證)
  • 想設計出鬆耦合、可測性高的程式結構
  • Refactor 前確保功能行為不變

🧩 TAD (Test After Development):

TAD是一種常見的測試導入方式,也就是開發完成後再加入測試,通常執行TAD會十分困難,因為程式碼可能大多是難以測試的結構,需要進行重構後才能進行撰寫測試(但仍可以先以局部重構的方式慢慢加入)。

優點:

  • 開發較快速直覺,無需先設計測試架構,可以快速 prototyping
  • 對於探索式開發較有彈性
  • 對需求不穩定的專案較友善

挑戰:

  • 測試容易被忽略或延後,累積技術債
  • 程式設計容易耦合難測,需重構後才能寫測試
  • 補寫的測試可能不完整,無法涵蓋所有邊界與例外情況
  • 測試維護成本提高,變更 A 功能可能造成 B 測試失效

適用情境:

  • 原型階段或需求還在變動
  • UI 互動、視覺細節尚未定案
  • 開發者想先掌握整體邏輯流程
  • 維護舊有系統時(寫回歸測試)

測試策略選用建議

大致建議: 新開發 → TDD , 既有專案 → TAD

類型優先建議策略
關鍵業務邏輯TDD
表單驗證 / 演算法邏輯TDD
UI 操作 / 非穩定需求TAD
舊專案補測試TAD
快速開發或驗證原型TAD(+ 後續補 TDD)
  • 在實務中,可視情況混用 TDD 與 TAD,不必強求一致。
  • 不論選用哪一種策略,測試的覆蓋度與品質才是關鍵。

測試重構原則

為了寫出容易測試的程式碼,有以下幾個原則可以依循著進行重構:

原則解釋實例
純函式優先無副作用、傳入固定輸入回傳固定結果filterData(data, keyword)
資料傳入傳出不直接修改全域或組件變數避免 this.xxx = ...
分離 concernUI 和邏輯分離onClick 只負責觸發,邏輯交給外部 utils
依賴注入函式接收外部依賴而不是硬編寫api.fetchList() 改為從參數傳入
小函式化拆分邏輯,一次只做一件事一個函式只處理篩選,一個只處理排序

若概括這些原則來說,就是讓函式不要有「副作用」,因為副作用會導致程式執行過程中,難以察覺的外部變化或影響,並且對這樣的函式寫測試時,會需要添加大量的 Mock 才能進行,測試成本變得很高,一旦修改也很容易造成測試損壞無法進行,所以函式應以"只操作傳入參數,並傳出結果"的方式撰寫 (像 utils 那樣可重用)。