<!-- title: Claude Code测试驱动开发全实战 -->

# Claude Code 测试驱动开发全实战：从 Red-Green-Refactor 到自动化质量守门

> **学习目标**：掌握用 Claude Code 实施严格 TDD 工作流的完整方法——包括 CLAUDE.md 测试规则配置、Red-Green-Refactor 循环实操、自定义 TDD Skill 编写、Hooks 自动化测试守门、以及一个完整的全栈项目实战案例。阅读完毕后，你将能在任何项目中让 Claude Code 严格遵循"测试先行"纪律，彻底告别 AI 默认的"实现先行"陷阱。

> **适用人群**：已具备 Claude Code 基础使用经验的前端/后端/全栈开发者，希望将 AI 编码助手纳入 TDD 纪律框架的工程师，以及团队技术负责人。

---

## 一、为什么 Claude Code 需要"被约束"的 TDD

### 1.1 Claude Code 的结构性缺陷：实现先行

Claude Code 是当前最强大的 AI 编码助手之一，但它有一个根深蒂固的行为倾向——**默认实现先行**（Implementation-First）。当你给它一个需求描述，它的第一反应是直接写功能代码，测试要么被忽略，要么被敷衍。

```
用户：帮我写一个用户注册功能

Claude Code（默认行为）：
  ✅ 立即创建 UserService.java
  ✅ 立即实现 register() 方法
  ✅ 顺手写个 Controller
  ❌ 没有先写测试
  ❌ 边界条件未覆盖
  ❌ 错误路径未验证
```

这不是 Claude Code 的 bug，而是大语言模型推理模式的固有特征——它倾向于从"最可能的解决方案"开始生成，而测试用例需要从"所有可能失败的场景"出发思考，两者思维方向截然相反。

### 1.2 TDD 的三层价值在 AI 时代更加凸显

| TDD 价值层 | 传统开发中的作用 | AI 辅助开发中的作用 |
|---|---|---|
| **需求澄清** | 帮助开发者理解需求 | 作为 AI 的精确需求规约，消除歧义 |
| **安全网** | 防止回归错误 | 验证 AI 生成代码的正确性，防止"看起来对但实际错" |
| **设计指引** | 驱动更好的 API 设计 | 约束 AI 的代码结构，防止过度工程化 |

### 1.3 Claude Code + TDD 的正确姿势

要让 Claude Code 真正遵循 TDD，需要三层防线：

```mermaid
graph TB
    subgraph "三层TDD防线"
        A["第一层：CLAUDE.md<br/>测试规则与质量标准"]
        B["第二层：Custom TDD Skill<br/>强制 Red-Green-Refactor 流程"]
        C["第三层：Hooks<br/>自动运行测试守门"]
    end
    A --> B --> C
    C -->|"测试失败则阻断"| D["阻止低质量代码合入"]
    style A fill:#f9f,stroke:#333
    style B fill:#bbf,stroke:#333
    style C fill:#bfb,stroke:#333
    style D fill:#fbb,stroke:#333
```

---

## 二、前置条件与环境准备

### 2.1 基础要求

- **Claude Code** >= 2.1.x（2026 年最新版本，默认模型 Opus 4.8）
- **Node.js** >= 18.x
- **Git** >= 2.40
- 至少熟悉一种测试框架：Jest / Vitest / pytest / Go test

### 2.2 安装与验证

```bash
# 安装 Claude Code（如果尚未安装）
npm install -g @anthropic-ai/claude-code

# 验证版本
claude --version
# 期望输出：2.1.x 或更高

# 进入你的项目目录
mkdir tdd-demo && cd tdd-demo
git init

# 初始化 Claude Code 项目配置
claude /init
```

### 2.3 测试框架选型建议

| 语言/框架 | 推荐测试工具 | 命令 |
|---|---|---|
| TypeScript/JavaScript | **Vitest**（推荐）或 Jest | `npx vitest` / `npx jest` |
| Python | **pytest** | `pytest` |
| Go | 标准库 testing + testify | `go test ./...` |
| Java | JUnit 5 + Mockito | `mvn test` |

> **本文所有示例使用 Vitest + TypeScript**，但原则适用于所有语言。

---

## 三、第一层防线：CLAUDE.md 测试规则配置

### 3.1 为什么 CLAUDE.md 是 TDD 的基石

CLAUDE.md 是 Claude Code 的"项目宪法"。在其中声明测试规则，等于告诉 AI："在这个项目中，测试不是可选的，而是强制的前置步骤。"

### 3.2 完整的测试规则配置

在项目根目录创建或编辑 `CLAUDE.md`，加入以下测试相关段落：

```markdown
# Testing Standards

## TDD Discipline (MANDATORY)
- ALWAYS write tests BEFORE implementation code
- Follow strict Red-Green-Refactor cycle:
  1. RED: Write a failing test that defines expected behavior
  2. GREEN: Write the MINIMUM code to make the test pass
  3. REFACTOR: Improve code while keeping all tests green
- NEVER skip the RED phase — tests must fail first to prove they test something

## Test Quality Rules
- Test behavior, NOT implementation details
- Use descriptive test names: `should [expected behavior] when [condition]`
- Each test must have exactly ONE assertion focus
- Cover: happy path, edge cases, error paths
- Minimum coverage target: 80% for new code
- NEVER mock what you don't own — wrap external dependencies behind interfaces

## Test Commands
- Run all tests: `npx vitest run`
- Run single file: `npx vitest run path/to/test.ts`
- Watch mode: `npx vitest`
- Coverage: `npx vitest run --coverage`

## File Naming Conventions
- Test files: `*.test.ts` or `*.spec.ts`
- Test directory mirrors source: `src/auth/login.ts` → `src/auth/login.test.ts`
- Test utilities: `test/helpers/` or `test/fixtures/`

## Forbidden Patterns
- ❌ DO NOT write `expect(true).toBe(true)` placeholder tests
- ❌ DO NOT test private methods directly
- ❌ DO NOT use `any` types in test code
- ❌ DO NOT skip failing tests with `.skip()` without a linked issue
```

### 3.3 规则生效验证

配置完成后，用以下命令验证 Claude Code 是否遵守规则：

```bash
claude "帮我创建一个计算器模块，支持加减乘除"
```

**预期行为**：
- Claude Code 应该**先创建测试文件** `calculator.test.ts`
- 然后运行测试，确认**红灯**（测试失败）
- 最后才写 `calculator.ts` 实现
- 运行测试，确认**绿灯**

如果 Claude Code 直接写了实现代码而没有先写测试，说明 CLAUDE.md 规则需要更明确的措辞，或者需要进入下一层——自定义 TDD Skill。

---

## 四、第二层防线：自定义 TDD Skill 强制流程

### 4.1 Skill 如何解决"AI 不守纪律"问题

CLAUDE.md 是"建议"，Skill 是"流程"。一个 TDD Skill 把 Red-Green-Refactor 编排为 Claude Code 必须遵循的子代理序列，每一步都有明确的输入输出和验证条件。

### 4.2 创建 TDD Skill

在项目根目录创建 `.claude/skills/tdd.md`：

```markdown
---
name: tdd
description: >
  Enforce strict Test-Driven Development. Use when implementing new features,
  fixing bugs, or refactoring code. Orchestrates the Red-Green-Refactor cycle
  through subagents, ensuring tests are written and verified BEFORE implementation.
---

You are a TDD discipline enforcer. When the user asks you to implement or modify
any functionality, you MUST follow this exact sequence:

## Phase 1: RED (Write Failing Test)

1. Analyze the user's requirement and identify the expected behavior
2. Create a test file following project conventions (*.test.ts)
3. Write test cases that cover:
   - Happy path (normal input → expected output)
   - Edge cases (boundary values, empty input, null/undefined)
   - Error paths (invalid input → expected error)
4. Run the test command: `npx vitest run <test-file>`
5. VERIFY the test FAILS — if it passes, the test is wrong
6. Report: "🔴 RED: <number> tests failing as expected"

## Phase 2: GREEN (Minimum Implementation)

1. Write the MINIMUM code required to make failing tests pass
2. Do NOT add extra features, optimizations, or "nice-to-haves"
3. Run the test command again: `npx vitest run <test-file>`
4. VERIFY ALL tests pass — if any still fail, fix implementation
5. Report: "🟢 GREEN: All tests passing"

## Phase 3: REFACTOR (Improve Code Quality)

1. Review the implementation for:
   - Code duplication
   - Poor naming
   - Violations of SOLID principles
   - Performance bottlenecks
2. Make improvements while keeping tests green
3. Run tests after EACH refactor step
4. Report: "♻️ REFACTOR: <list of improvements made>"

## Rules
- NEVER skip Phase 1 (RED)
- NEVER implement more than what tests require in Phase 2 (GREEN)
- NEVER break tests during Phase 3 (REFACTOR)
- If user asks to skip tests, respond: "TDD is mandatory in this project. I'll proceed with the full Red-Green-Refactor cycle."
```

### 4.3 TDD Skill 的执行流程

```mermaid
sequenceDiagram
    participant U as 用户
    participant CC as Claude Code
    participant T as 测试框架(Vitest)
    participant S as 源代码

    U->>CC: /tdd 实现 XXX 功能

    rect rgb(255, 200, 200)
        Note over CC,T: Phase 1: RED
        CC->>T: 编写测试用例
        CC->>T: 运行 npx vitest run
        T-->>CC: ❌ 测试失败(预期)
        CC->>U: 🔴 RED: 3 tests failing
    end

    rect rgb(200, 255, 200)
        Note over CC,S: Phase 2: GREEN
        CC->>S: 编写最小实现
        CC->>T: 运行 npx vitest run
        T-->>CC: ✅ 测试全部通过
        CC->>U: 🟢 GREEN: All tests passing
    end

    rect rgb(200, 220, 255)
        Note over CC,S: Phase 3: REFACTOR
        CC->>S: 重构改进代码
        CC->>T: 每次重构后运行测试
        T-->>CC: ✅ 测试仍然通过
        CC->>U: ♻️ REFACTOR: 提取公共方法+优化命名
    end
```

### 4.4 使用 TDD Skill

```bash
# 方式一：直接调用
claude "/tdd 实现一个用户认证模块，支持邮箱密码注册和登录"

# 方式二：在对话中触发
claude
> 用TDD方式帮我实现购物车的计算总价功能
# Claude Code 会自动检测到 "实现" 关键词，按照 TDD 流程执行
```

---

## 五、第三层防线：Hooks 自动化测试守门

### 5.1 什么是 Hooks

Hooks 是 Claude Code 的生命周期钩子——在特定事件发生时自动执行 shell 命令。对于 TDD，我们主要用两类 Hook：

- **PostToolUse**：在 Claude Code 修改文件后自动运行测试
- **PreToolUse**：在 Claude Code 执行操作前进行校验

### 5.2 配置自动化测试 Hook

编辑项目级配置文件 `.claude/settings.json`：

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "cd \"$PROJECT_DIR\" && npx vitest run --reporter=verbose 2>&1 | tail -20"
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "sh -c 'FILE=\"$CLAUDE_FILE_PATH\"; if echo \"$FILE\" | grep -qv \"\\.test\\.\"; then echo \"⚠️ Source file modified — ensure corresponding tests exist\"; fi'"
          }
        ]
      }
    ]
  }
}
```

### 5.3 Hook 工作流程

```mermaid
flowchart LR
    A["Claude Code<br/>修改文件"] --> B{"PreToolUse Hook<br/>源文件变更?"}
    B -->|"是"| C["提示: 确认测试存在"]
    B -->|"否(测试文件)"| D["正常执行"]
    C --> D
    D --> E["文件写入完成"]
    E --> F["PostToolUse Hook<br/>自动运行测试"]
    F --> G{"测试通过?"}
    G -->|"✅ 通过"| H["继续下一个任务"]
    G -->|"❌ 失败"| I["输出失败详情<br/>Claude Code 自动修复"]
    I --> A
```

### 5.4 更精细的 Hook：按文件类型分别处理

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "sh -c 'FILE=\"$CLAUDE_FILE_PATH\"; if echo \"$FILE\" | grep -q \"\\.test\\.\\|\\.spec\\.\"; then echo \"🧪 Test file modified, running related tests...\"; npx vitest run \"$FILE\" 2>&1 | tail -15; else SRC=\"${FILE%.ts}.test.ts\"; if [ -f \"$SRC\" ]; then echo \"📦 Source modified, running its tests...\"; npx vitest run \"$SRC\" 2>&1 | tail -15; fi; fi'"
          }
        ]
      }
    ]
  }
}
```

这个 Hook 做到了：
- 如果修改的是**测试文件** → 只运行该测试文件
- 如果修改的是**源文件** → 自动找到对应测试文件并运行
- 其他文件修改 → 不触发测试

---

## 六、实战案例：用 TDD 构建任务管理 API

### 6.1 项目概述

我们将用 Claude Code 的 TDD 工作流构建一个 **Task Manager REST API**，包含以下功能：

- 创建任务（标题、描述、优先级、截止日期）
- 查询任务列表（支持过滤和分页）
- 更新任务状态（待办 → 进行中 → 已完成）
- 删除任务
- 任务过期自动标记

### 6.2 Step 1：初始化项目

```bash
mkdir task-manager-api && cd task-manager-api
git init
npm init -y
npm install express zod uuid
npm install -D vitest typescript @types/express @types/uuid tsx

# 创建 Claude Code 配置
claude /init
```

### 6.3 Step 2：配置 CLAUDE.md 测试规则

将前面第三节的 CLAUDE.md 测试规则配置写入项目的 `CLAUDE.md`，并追加项目特定内容：

```markdown
# Project: Task Manager API

## Architecture
- Language: TypeScript
- Framework: Express.js
- Validation: Zod schemas
- Testing: Vitest
- Source structure:
  ```
  src/
    models/       # Data models and types
    services/     # Business logic
    routes/       # Express route handlers
    validators/   # Zod schemas
    errors/       # Custom error classes
  ```

## Test Strategy
- Unit tests: services, validators, models
- Integration tests: routes (using supertest-like approach)
- Each service method gets its own describe block
- Use dependency injection for testability
```

### 6.4 Step 3：TDD 实战 — 创建任务功能

启动 Claude Code 并触发 TDD Skill：

```bash
claude "/tdd 实现创建任务功能：POST /api/tasks，接受 title(必填)、description(可选)、priority(low/medium/high, 默认medium)、dueDate(可选ISO日期)，返回创建的task对象"
```

**Claude Code 的完整执行过程**：

#### Phase 1 — RED 🔴

Claude Code 首先创建测试文件 `src/services/task.service.test.ts`：

```typescript
import { describe, it, expect, beforeEach } from 'vitest';
import { TaskService } from './task.service';
import { TaskRepository } from '../repositories/task.repository';

describe('TaskService - createTask', () => {
  let taskService: TaskService;
  let mockRepository: TaskRepository;

  beforeEach(() => {
    mockRepository = {
      save: vi.fn(),
      findById: vi.fn(),
      findAll: vi.fn(),
      delete: vi.fn(),
    } as unknown as TaskRepository;
    taskService = new TaskService(mockRepository);
  });

  it('should create a task with required fields only', async () => {
    const input = { title: 'Buy groceries' };
    mockRepository.save = vi.fn().mockResolvedValue({
      id: 'task-1',
      title: 'Buy groceries',
      description: null,
      priority: 'medium',
      status: 'todo',
      dueDate: null,
      createdAt: new Date(),
    });

    const result = await taskService.createTask(input);

    expect(result.title).toBe('Buy groceries');
    expect(result.priority).toBe('medium');
    expect(result.status).toBe('todo');
    expect(mockRepository.save).toHaveBeenCalledOnce();
  });

  it('should create a task with all fields', async () => {
    const input = {
      title: 'Write report',
      description: 'Q4 financial report',
      priority: 'high' as const,
      dueDate: '2026-07-15',
    };
    mockRepository.save = vi.fn().mockResolvedValue({
      id: 'task-2',
      ...input,
      status: 'todo',
      createdAt: new Date(),
    });

    const result = await taskService.createTask(input);

    expect(result.title).toBe('Write report');
    expect(result.priority).toBe('high');
    expect(result.dueDate).toBe('2026-07-15');
  });

  it('should reject empty title', async () => {
    const input = { title: '' };

    await expect(taskService.createTask(input)).rejects.toThrow(
      'Title is required'
    );
  });

  it('should reject invalid priority value', async () => {
    const input = { title: 'Test', priority: 'urgent' };

    await expect(taskService.createTask(input)).rejects.toThrow();
  });

  it('should reject past due dates', async () => {
    const input = { title: 'Test', dueDate: '2020-01-01' };

    await expect(taskService.createTask(input)).rejects.toThrow(
      'Due date must be in the future'
    );
  });
});
```

Claude Code 运行测试：

```bash
npx vitest run src/services/task.service.test.ts
```

输出：

```
❯ npx vitest run src/services/task.service.test.ts

 FAIL  src/services/task.service.test.ts
  TaskService - createTask
    ✗ should create a task with required fields only
    ✗ should create a task with all fields
    ✗ should reject empty title
    ✗ should reject invalid priority value
    ✗ should reject past due dates

🔴 RED: 5 tests failing as expected (module not found)
```

#### Phase 2 — GREEN 🟢

Claude Code 创建最小实现文件：

`src/models/task.types.ts`：

```typescript
export type Priority = 'low' | 'medium' | 'high';
export type Status = 'todo' | 'in_progress' | 'done';

export interface Task {
  id: string;
  title: string;
  description: string | null;
  priority: Priority;
  status: Status;
  dueDate: string | null;
  createdAt: Date;
}

export interface CreateTaskInput {
  title: string;
  description?: string;
  priority?: Priority;
  dueDate?: string;
}
```

`src/repositories/task.repository.ts`：

```typescript
import { Task } from '../models/task.types';

export interface TaskRepository {
  save(task: Omit<Task, 'id' | 'createdAt'>): Promise<Task>;
  findById(id: string): Promise<Task | null>;
  findAll(filter?: Record<string, unknown>): Promise<Task[]>;
  delete(id: string): Promise<boolean>;
}
```

`src/services/task.service.ts`：

```typescript
import { v4 as uuidv4 } from 'uuid';
import { TaskRepository } from '../repositories/task.repository';
import { CreateTaskInput, Priority, Task } from '../models/task.types';

export class TaskService {
  constructor(private repo: TaskRepository) {}

  async createTask(input: CreateTaskInput): Promise<Task> {
    // Validate title
    if (!input.title || input.title.trim() === '') {
      throw new Error('Title is required');
    }

    // Validate priority
    const validPriorities: Priority[] = ['low', 'medium', 'high'];
    const priority = input.priority ?? 'medium';
    if (!validPriorities.includes(priority)) {
      throw new Error(`Invalid priority: ${input.priority}`);
    }

    // Validate due date
    if (input.dueDate) {
      const dueDate = new Date(input.dueDate);
      if (dueDate <= new Date()) {
        throw new Error('Due date must be in the future');
      }
    }

    const task: Task = {
      id: uuidv4(),
      title: input.title,
      description: input.description ?? null,
      priority,
      status: 'todo',
      dueDate: input.dueDate ?? null,
      createdAt: new Date(),
    };

    return this.repo.save(task);
  }
}
```

运行测试：

```
✅ GREEN: All 5 tests passing
```

#### Phase 3 — REFACTOR ♻️

Claude Code 检查代码并提出改进：

```typescript
// 重构：提取验证逻辑到独立模块
// src/validators/task.validator.ts
import { Priority } from '../models/task.types';

const VALID_PRIORITIES: Priority[] = ['low', 'medium', 'high'];

export function validateTitle(title: string): void {
  if (!title || title.trim() === '') {
    throw new Error('Title is required');
  }
}

export function validatePriority(priority: string): Priority {
  if (!VALID_PRIORITIES.includes(priority as Priority)) {
    throw new Error(`Invalid priority: ${priority}`);
  }
  return priority as Priority;
}

export function validateDueDate(dateStr: string): void {
  const dueDate = new Date(dateStr);
  if (dueDate <= new Date()) {
    throw new Error('Due date must be in the future');
  }
}
```

重构后 `TaskService` 变得更简洁：

```typescript
export class TaskService {
  constructor(private repo: TaskRepository) {}

  async createTask(input: CreateTaskInput): Promise<Task> {
    validateTitle(input.title);
    const priority = input.priority
      ? validatePriority(input.priority)
      : 'medium';
    if (input.dueDate) validateDueDate(input.dueDate);

    const task: Task = {
      id: uuidv4(),
      title: input.title,
      description: input.description ?? null,
      priority,
      status: 'todo',
      dueDate: input.dueDate ?? null,
      createdAt: new Date(),
    };

    return this.repo.save(task);
  }
}
```

每次重构后自动运行测试 → 全部通过 → `♻️ REFACTOR: 提取验证逻辑到独立模块，TaskService 职责更单一`

### 6.5 Step 4：继续 TDD — 更多功能

按照相同模式，逐一用 TDD 实现剩余功能：

```bash
# 查询功能
claude "/tdd 实现查询任务列表：GET /api/tasks，支持 status 过滤和 page/limit 分页"

# 状态更新
claude "/tdd 实现任务状态流转：PATCH /api/tasks/:id/status，只允许 todo→in_progress→done 的正向流转"

# 删除功能
claude "/tdd 实现删除任务：DELETE /api/tasks/:id，返回204，任务不存在返回404"

# 过期检测
claude "/tdd 实现过期自动标记：系统检查到期日已过的任务，将其标记为expired状态"
```

### 6.6 项目最终结构

```
task-manager-api/
├── CLAUDE.md                    # TDD规则 + 项目约定
├── .claude/
│   ├── settings.json            # Hooks配置
│   └── skills/
│       └── tdd.md               # 自定义TDD Skill
├── src/
│   ├── models/
│   │   ├── task.types.ts
│   │   └── task.types.test.ts
│   ├── services/
│   │   ├── task.service.ts
│   │   └── task.service.test.ts
│   ├── validators/
│   │   ├── task.validator.ts
│   │   └── task.validator.test.ts
│   ├── routes/
│   │   ├── task.routes.ts
│   │   └── task.routes.test.ts
│   └── errors/
│       └── app-error.ts
├── package.json
├── vitest.config.ts
└── tsconfig.json
```

---

## 七、高级技巧：让 TDD 更高效的五种模式

### 7.1 模式一：测试先行提示模板

与其每次都解释需求，不如创建一个标准化的提示模板：

```markdown
<!-- .claude/skills/tdd-feature.md -->
---
name: tdd-feature
description: Start TDD for a new feature with structured requirements
---

Implement the following feature using strict TDD:

## Feature: {{FEATURE_NAME}}

### Acceptance Criteria:
{{ACCEPTANCE_CRITERIA}}

### Test Cases to Cover:
1. Happy path: {{HAPPY_PATH}}
2. Edge cases: {{EDGE_CASES}}
3. Error paths: {{ERROR_PATHS}}

### Technical Notes:
- Follow existing patterns in the codebase
- Run `npx vitest run` after each phase
- Use dependency injection for testability
```

使用方式：

```bash
claude "/tdd-feature FEATURE_NAME='用户密码重置' ACCEPTANCE_CRITERIA='输入邮箱发送重置链接，链接24小时有效' HAPPY_PATH='已注册邮箱收到重置邮件' EDGE_CASES='未注册邮箱返回相同响应防止枚举' ERROR_PATHS='无效邮箱格式, 请求频率超限'"
```

### 7.2 模式二：/review + /verify 双重验证

Claude Code 内置两个强大的代码审查命令，在 TDD 流程中配合使用：

```bash
# /review：对当前 git diff 做代码审查
claude "/review"

# /verify：运行应用并实际验证功能是否正常
claude "/verify"

# 组合使用：TDD 完成一个功能后
claude "我刚用TDD完成了密码重置功能，请先 /review 我的代码变更，然后 /verify 确认功能正常"
```

### 7.3 模式三：覆盖率驱动的迭代

```bash
# 先检查当前覆盖率
claude "运行 npx vitest run --coverage 并分析覆盖率报告，找出覆盖率低于80%的模块"

# 针对性补充测试
claude "/tdd 为覆盖率不足的模块补充测试，优先覆盖未测试的分支"
```

### 7.4 模式四：Bug 修复也走 TDD

Bug 修复是最容易跳过测试的场景，但恰恰最需要 TDD：

```bash
claude "/tdd 修复以下bug：当用户创建任务时不填priority字段，返回500错误而不是使用默认值medium。

复现步骤：
1. POST /api/tasks body: {title: 'test'}
2. 期望返回 priority: 'medium'
3. 实际返回 500 Internal Server Error

先写一个能复现该bug的测试（RED），然后修复代码（GREEN），最后确认没有引入回归（REFACTOR）。"
```

### 7.5 模式五：批量化 TDD 与进度追踪

对于需要一次性实现多个功能的场景：

```bash
# 使用 TaskCreate 创建任务列表
claude "分析以下需求文档(requirements.md)，用 /tdd 逐个实现每个功能点，每完成一个就运行测试确认，然后标记完成并继续下一个"
```

```mermaid
flowchart TD
    A["需求文档"] --> B["Claude Code 拆分功能点"]
    B --> C["功能1: TDD循环"]
    C --> D["功能2: TDD循环"]
    D --> E["功能3: TDD循环"]
    E --> F["功能N: TDD循环"]
    F --> G["全量测试"]
    G --> H{"覆盖率 ≥ 80%?"}
    H -->|"是"| I["✅ 完成"]
    H -->|"否"| J["补充测试"]
    J --> G

    subgraph "每个TDD循环"
        C1["🔴 RED"] --> C2["🟢 GREEN"] --> C3["♻️ REFACTOR"]
    end
```

---

## 八、常见问题与解决方案

### Q1：Claude Code 还是先写了实现怎么办？

**根因**：CLAUDE.md 的 TDD 规则可能被更急迫的上下文"淹没"。

**解决方案**：
1. 确保 TDD 规则在 CLAUDE.md 的**最前面**
2. 使用自定义 Skill（`/tdd`）而非自然语言指令
3. 在 Hook 中增加硬性阻断：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [{
          "type": "command",
          "command": "sh -c 'FILE=\"$CLAUDE_FILE_PATH\"; if echo \"$FILE\" | grep -qv \"\\.test\\.\\|\\.spec\\.\\|CLAUDE\\|settings\"; then TESTFILE=$(echo \"$FILE\" | sed \"s/\\.ts$/.test.ts/\"); if [ ! -f \"$TESTFILE\" ]; then echo \"⛔ BLOCKED: No test file found for $FILE. Create $TESTFILE first.\"; exit 1; fi; fi'"
        }]
      }
    ]
  }
}
```

这个 Hook 会**阻止** Claude Code 创建源文件——除非对应的测试文件已经存在。

### Q2：AI 生成的测试质量低怎么办？

**解决方案**：在 CLAUDE.md 中增加具体的测试质量标准：

```markdown
## Test Quality Checklist (Claude MUST verify before submitting)
- [ ] Test name describes expected behavior, not implementation
- [ ] Arrange-Act-Assert pattern is clear
- [ ] No hardcoded dates or IDs — use factories/fixtures
- [ ] Mocks only for external dependencies, not for domain logic
- [ ] Edge cases covered: empty input, null, undefined, boundary values
- [ ] Error messages are asserted, not just error types
```

### Q3：TDD 太慢，影响开发效率？

**平衡策略**：不是所有代码都需要严格 TDD。在 CLAUDE.md 中明确分级：

```markdown
## TDD Enforcement Levels
- **Level 3 (Strict)**: Business logic, payment, auth, data transformation → Full Red-Green-Refactor
- **Level 2 (Standard)**: API routes, middleware, data access → Test + Implement together
- **Level 1 (Light)**: Config files, types, constants → No test required
```

### Q4：如何在已有项目中引入 TDD？

**渐进式策略**：

```bash
# 第一步：只为新增代码强制 TDD
claude "分析当前代码库中哪些模块有测试、哪些没有。为新功能开发制定 TDD 规则，存量代码暂不要求。"

# 第二步：逐步为高风险模块补测试
claude "/tdd 为 src/services/payment.service.ts 补充测试，它处理支付逻辑但目前0测试覆盖"

# 第三步：设置覆盖率基线，只升不降
# 在 vitest.config.ts 中配置：
# coverage: { thresholds: { lines: 60, branches: 50, functions: 60 } }
```

---

## 九、TDD 全流程架构总览

```mermaid
graph TB
    subgraph "用户输入"
        REQ["功能需求 / Bug描述"]
    end

    subgraph "Claude Code TDD 引擎"
        SKILL["/tdd Skill<br/>流程编排"]
        RED["🔴 RED Phase<br/>生成测试代码"]
        GREEN["🟢 GREEN Phase<br/>最小实现"]
        REFACTOR["♻️ REFACTOR Phase<br/>代码改进"]
    end

    subgraph "三层防线"
        CMD["CLAUDE.md<br/>测试规则"]
        HOOK["Hooks<br/>自动守门"]
        REVIEW["/review + /verify<br/>质量审查"]
    end

    subgraph "测试基础设施"
        VITEST["Vitest<br/>测试运行器"]
        COV["Coverage<br/>覆盖率报告"]
        CI["CI Pipeline<br/>持续集成"]
    end

    REQ --> SKILL
    CMD --> SKILL
    SKILL --> RED
    RED -->|"测试失败"| GREEN
    GREEN -->|"测试通过"| REFACTOR
    REFACTOR -->|"测试仍通过"| REVIEW
    HOOK -->|"每次文件变更触发"| VITEST
    REVIEW --> VITEST
    VITEST --> COV
    COV --> CI

    style RED fill:#ffcccc,stroke:#cc0000
    style GREEN fill:#ccffcc,stroke:#00cc00
    style REFACTOR fill:#ccccff,stroke:#0000cc
    style CMD fill:#fff3cd,stroke:#856404
    style HOOK fill:#d4edda,stroke:#155724
    style REVIEW fill:#cce5ff,stroke:#004085
```

---

## 十、不同语言/框架的 TDD 配置速查

### Python + pytest

```markdown
# CLAUDE.md testing section (Python version)
## Test Commands
- Run all: `pytest`
- Run single: `pytest tests/test_feature.py -v`
- Coverage: `pytest --cov=src --cov-report=term-missing`

## Conventions
- Test files: `tests/test_*.py`
- Fixtures in `tests/conftest.py`
- Use `pytest.raises` for exception testing
- Factory pattern with `factory_boy` for test data
```

### Go + testing

```markdown
# CLAUDE.md testing section (Go version)
## Test Commands
- Run all: `go test ./...`
- Run single: `go test ./pkg/service -v`
- Coverage: `go test -cover ./...`
- Race detection: `go test -race ./...`

## Conventions
- Test files: `*_test.go` in same package
- Table-driven tests using `t.Run`
- Use `testify/assert` for readable assertions
- Interfaces for dependency injection
```

---

## 延伸阅读

| 资源 | 说明 |
|---|---|
| [Anthropic 官方 Claude Code 文档](https://code.claude.com/docs) | Slash Commands、Hooks、Skills 完整参考 |
| [Claude Code Hooks 官方指南](https://code.claude.com/docs/en/hooks-guide) | 所有生命周期钩子的详细说明 |
| [Claude Code TDD Skill 实战](https://alexop.dev/posts/custom-tdd-workflow-claude-code-vue/) | 作者 Alexander Op 细致的 Skill 编写教程 |
| [Claude Code 测试生成实践指南](https://32blog.com/en/claude-code/claude-code-test-generation-practical-guide) | CLAUDE.md 规则 + Hooks + TDD 三层体系 |
| [Claude Code TDD Skill 实现](https://docs.bswen.com/blog/2026-03-25-tdd-skill-claude-code/) | 具体的 Skill 代码和执行流程 |
| [Claude Code 命令速查表](https://computingforgeeks.com/claude-code-cheat-sheet/) | 70+ slash commands 和 CLI flags 完整清单 |

---

## 训练营适用性评估

| 评估维度 | 说明 |
|---|---|
| **适用训练营类型** | AI 辅助开发训练营、高级软件工程训练营、质量工程实战营 |
| **学员基础要求** | TypeScript/Python 基础 + Claude Code 入门经验 + 了解单元测试概念 |
| **预计教学时长** | 4-6 小时（含动手实操） |
| **推荐教学节奏** | 第1小时：理论+CLAUDE.md配置 → 第2-3小时：TDD Skill+Hooks实操 → 第4-5小时：完整项目实战 → 第6小时：回顾+Q&A |
| **硬件要求** | 每人一台笔记本，已安装 Claude Code + Node.js + Git |
| **分组建议** | 2-3人一组，一人写需求/验收，一人操作 Claude Code，一人审查输出 |

---

## 参考来源

1. [A Claude Code TDD Skill: Forcing Red-Green-Refactor Discipline — alexop.dev](https://alexop.dev/posts/custom-tdd-workflow-claude-code-vue/) — 自定义 TDD Skill 的完整实现，包含 Skill 代码和执行效果
2. [Claude Code Test Generation: A Practical Guide — 32blog](https://32blog.com/en/claude-code/claude-code-test-generation-practical-guide) — CLAUDE.md 测试规则、Hooks 自动化、TDD 工作流三层体系实践指南
3. [How to Implement TDD with Claude Code TDD Skill — BSWEN](https://docs.bswen.com/blog/2026-03-25-tdd-skill-claude-code/) — Claude Code TDD Skill 的配置方法和使用流程
4. [Claude Code Cheat Sheet — ComputingForGeeks](https://computingforgeeks.com/claude-code-cheat-sheet/) — Claude Code 2.1.x 全命令速查，包含 Slash Commands 和 Hooks 参考
5. [Automate Actions with Hooks — Claude Code Official Docs](https://code.claude.com/docs/en/hooks-guide) — Anthropic 官方 Hooks 生命周期和配置文档

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
