跳轉到

5.1 為什麼要測試?測試金字塔#

沒有測試的代價#

你改了一行程式碼,覺得沒問題就上線了——結果弄壞了三個月前寫的另一個功能。這叫回歸(regression),是沒有測試的專案最常見的災難。

沒有測試的團隊特徵:

  1. 不敢改程式:怕動到不知道的東西,技術債越積越多
  2. 人肉測試:每次上線前手動點一遍所有功能,慢又容易漏
  3. 重構是賭博:不知道改完之後對不對

測試解決的核心問題:程式碼的每一次變更,都有機器自動驗證對不對。

測試金字塔#

        /  E2E  \        少:模擬真實使用者的完整流程(慢、貴)
       / 整合測試 \       中:驗證多個模組組合起來的行為
      /  單元測試  \      多:驗證單一函式的行為(快、便宜)
層級 測什麼 速度 數量
單元測試 單一函式 / 模組 毫秒級 最多
整合測試 多模組組合、API + 資料庫 秒級 適量
E2E 測試 完整使用流程 分鐘級 少量關鍵路徑

原則:底層的單元測試要多、要快;頂層的 E2E 只測關鍵路徑。反過來(大量 E2E)的專案會又慢又不穩定。

好測試的特徵#

一個單元測試只驗證一件事,結構是三段式(AAA):

test("divide 應該正確計算", () => {
  // Arrange(準備)
  const result = divide(10, 2);
  // Assert(驗證)
  assert.equal(result, 5);
});
  • 快:單元測試應該毫秒級完成,慢了你就不會常跑
  • 獨立:測試之間不互相依賴,順序打亂也能過
  • 可重複:任何時候、任何機器上跑結果都一樣

測試什麼時候寫?#

  • TDD(Test-Driven Development):先寫測試再寫程式,適合邏輯明確的功能
  • 實務折衷:至少在修 bug 時先寫一個「會失敗的測試」重現 bug,修好後它變成回歸防護

心法:測試不是為了「證明程式對」,而是為了「讓你有勇氣改程式」。有測試的重構是工程,沒測試的重構是賭博。