跳至主要內容
精選 TDD Testing Workflow Automation

Claude Code TDD:AI 輔助測試驅動開發完整指南

學習如何用 Claude Code 實踐 TDD。包含完整的 Red-Green-Refactor 流程、Hooks 自動化配置,以及 CLAUDE.md 設定範例。

2026年1月19日 10 min read 作者:Claude World

TDD(測試驅動開發)是 Anthropic 官方推薦的 Claude Code 工作流程之一。這篇文章教你如何讓 Claude 自動遵循 Red-Green-Refactor 循環,寫出品質更高的程式碼。


為什麼選擇 TDD + Claude Code?

Claude Code 最擅長的是有明確目標的任務。測試就是最好的目標:

傳統方式:寫程式碼 → 手動測試 → 發現 bug → 修復 → 重複

TDD:寫測試 → 測試失敗(Red)→ 寫程式碼讓測試通過(Green)→ 重構

Claude + TDD 的優勢

優勢說明
明確的成功標準測試通過 = 任務完成
自動迭代Claude 可以執行測試、查看結果、修復問題
減少來回確認不需要手動確認「這樣有沒有成功?」
程式碼品質自然地具備測試覆蓋率

TDD 基礎:Red-Green-Refactor

三個階段

┌─────────────────────────────────────────────────────────┐
│                                                         │
│    🔴 RED          🟢 GREEN         🔄 REFACTOR        │
│                                                         │
│    寫一個會        寫最少量的        改善程式碼          │
│    失敗的測試      程式碼讓測試通過   保持測試通過        │
│                                                         │
│         │              │               │               │
│         ▼              ▼               ▼               │
│    測試必須失敗    測試必須通過    測試仍然通過          │
│                                                         │
└─────────────────────────────────────────────────────────┘

實際範例

步驟一:Red

你:寫一個測試,驗證 add(2, 3) 回傳 5

Claude:
// add.test.js
test('add(2, 3) should return 5', () => {
  expect(add(2, 3)).toBe(5);
});

// 執行測試
npm test
// ❌ FAIL - add is not defined

步驟二:Green

你:讓測試通過

Claude:
// add.js
function add(a, b) {
  return a + b;
}

// 執行測試
npm test
// ✅ PASS

步驟三:Refactor

你:重構程式碼,加上型別檢查

Claude:
// add.ts
function add(a: number, b: number): number {
  return a + b;
}

// 執行測試
npm test
// ✅ PASS(測試仍然通過)

CLAUDE.md 配置

基本 TDD 規則

在專案根目錄的 CLAUDE.md 中加入:

# TDD 開發規則

## 核心原則
1. **測試優先**:任何新功能都必須先有失敗的測試
2. **最小實作**:只寫剛好能讓測試通過的程式碼
3. **持續重構**:每次亮綠燈後考慮重構

## 開發流程
1. 接到需求 → 先寫測試
2. 確認測試失敗(Red)
3. 寫最少量程式碼讓測試通過(Green)
4. 重構(保持 Green)
5. 重複

## 禁止事項
- ❌ 不要在沒有測試的情況下寫功能程式碼
- ❌ 不要刪除或跳過現有測試
- ❌ 不要寫「等等再補測試」的程式碼

Hooks 自動化配置

自動執行測試

每次修改程式碼後自動執行測試:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm test -- --passWithNoTests --watchAll=false 2>/dev/null",
            "onFailure": "warn"
          }
        ]
      }
    ]
  }
}

強制 TDD:測試通過才能完成

{
  "hooks": {
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "npm test -- --passWithNoTests",
            "onFailure": "block"
          }
        ]
      }
    ]
  }
}

完整 TDD Hook 配置

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "Check if writing feature code. If yes, confirm corresponding test file exists. If test doesn't exist, remind to write tests first. Return 'approve' or reminder message."
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm test -- --passWithNoTests --watchAll=false",
            "onFailure": "warn"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "Check: 1) Was feature code added or modified? 2) If yes, do corresponding tests exist and pass? If tests don't exist or fail, return 'block' with explanation. Otherwise return 'approve'."
          },
          {
            "type": "command",
            "command": "npm test",
            "onFailure": "block"
          }
        ]
      }
    ]
  }
}

實戰範例:Todo 應用程式

讓我們用 TDD 實作一個簡單的 Todo 功能。

步驟一:定義需求

需求:實作 TodoList 類別
- addTodo(text):新增待辦事項
- getTodos():取得所有待辦事項
- completeTodo(id):標記為已完成
- getCompletedCount():取得已完成的數量

步驟二:第一個測試(Red)

你:用 TDD 實作 TodoList。先寫第一個測試:新增待辦事項。

Claude 生成:

// todoList.test.js
const { TodoList } = require('./todoList');

describe('TodoList', () => {
  describe('addTodo', () => {
    test('should add a todo item', () => {
      // Arrange
      const todoList = new TodoList();

      // Act
      todoList.addTodo('Buy milk');

      // Assert
      const todos = todoList.getTodos();
      expect(todos).toHaveLength(1);
      expect(todos[0].text).toBe('Buy milk');
    });
  });
});

執行測試:

npm test
# ❌ FAIL - Cannot find module './todoList'

步驟三:最小實作(Green)

你:讓測試通過,寫最少量的程式碼。

Claude 生成:

// todoList.js
class TodoList {
  constructor() {
    this.todos = [];
  }

  addTodo(text) {
    this.todos.push({ text });
  }

  getTodos() {
    return this.todos;
  }
}

module.exports = { TodoList };

執行測試:

npm test
# ✅ PASS

步驟四:下一個測試

你:繼續 TDD,加入 completeTodo 功能的測試。
// todoList.test.js(新增)
describe('completeTodo', () => {
  test('should mark a todo as completed', () => {
    // Arrange
    const todoList = new TodoList();
    todoList.addTodo('Buy milk');
    const todoId = todoList.getTodos()[0].id;

    // Act
    todoList.completeTodo(todoId);

    // Assert
    const todo = todoList.getTodos()[0];
    expect(todo.completed).toBe(true);
  });
});
npm test
# ❌ FAIL - todo.id is undefined

步驟五:擴充實作

你:讓測試通過。
// todoList.js(更新版)
class TodoList {
  constructor() {
    this.todos = [];
    this.nextId = 1;
  }

  addTodo(text) {
    this.todos.push({
      id: this.nextId++,
      text,
      completed: false
    });
  }

  getTodos() {
    return this.todos;
  }

  completeTodo(id) {
    const todo = this.todos.find(t => t.id === id);
    if (todo) {
      todo.completed = true;
    }
  }
}

module.exports = { TodoList };
npm test
# ✅ PASS(共 2 個測試)

TDD 常見問題

Q:哪些情況不適合 TDD?

A

  • 探索性的原型開發(還不確定要做什麼)
  • UI 樣式調整
  • 設定檔變更

這些情況下,可以先寫程式碼,之後再補測試。

Q:測試要寫多詳細?

A:遵循測試金字塔:

      /\
     /  \     E2E(少量)
    /----\
   /      \   整合測試(中等)
  /--------\
 /          \ 單元測試(大量)

Q:Claude 跳過測試直接寫程式碼怎麼辦?

A:在提示詞中明確說明:

你:用 TDD 實作這個功能。
    步驟一:先寫會失敗的測試
    步驟二:等我確認測試失敗後,再寫程式碼

或者使用 Hooks 強制執行:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "If writing feature code (not tests), check if test file exists. If not, return 'block' and remind to write tests first."
          }
        ]
      }
    ]
  }
}

最佳實踐總結

1. 提示詞範本

用 TDD 實作 [功能描述]:
1. 先寫會失敗的測試
2. 確認測試失敗後,寫最少量程式碼讓測試通過
3. 所有測試通過後,考慮重構

2. 檢查清單

每個新功能:

  • 先寫測試
  • 確認測試失敗(Red)
  • 寫程式碼讓測試通過(Green)
  • 重構(保持 Green)
  • 檢查覆蓋率

3. 推薦配置組合

工具用途
CLAUDE.md定義 TDD 規則
Hooks自動執行測試
Stop Hook強制測試通過

下一步

掌握 TDD 工作流程後,建議繼續閱讀:

  1. Hooks 完整教學 - 更多自動化配置
  2. 自訂 Agents - 建立專屬的測試 agent
  3. Director Mode - 進階開發模式

參考資源


最後更新:2026-01-19