测试驱动开发Skill tdd

测试驱动开发(TDD)是一种软件开发实践,通过在编写功能代码之前先编写测试用例来驱动开发过程,确保代码质量、可维护性和正确性。它遵循RED-GREEN-REFACTOR循环,强调测试作为设计工具,适用于新功能开发、bug修复和代码重构。关键词:测试驱动开发、TDD、单元测试、软件开发、RED-GREEN-REFACTOR、代码质量、测试先行。

测试 0 次安装 0 次浏览 更新于 3/19/2026

name: tdd description: “测试驱动开发工作流,采用RED-GREEN-REFACTOR方法,借鉴自Kent Beck、Michael Feathers和Ousterhout的反驳观点” tags:

  • 测试
  • 工作流
  • 方法论
  • tdd

测试驱动开发 (TDD)

节奏:RED-GREEN-REFACTOR

1. RED    - 首先编写失败的测试(定义预期行为)
2. GREEN  - 最小实现以通过(不要过度设计)
3. REFACTOR - 清理、消除重复,再次运行测试

为什么TDD有效(传说)

Kent Beck(《测试驱动开发:示例》)

“编写单元测试的行为更像是设计行为而非验证行为。”

  • 测试成为意图的可执行文档
  • “假装直到成功” - 从硬编码值开始,逐步泛化
  • 小步骤减少调试时间
  • 重构的信心来自测试覆盖

Michael Feathers(《有效处理遗留代码》)

“我所知的最强大的功能添加技术是测试驱动开发。”

  • TDD在面向对象和过程代码中都有效
  • 先写测试强迫你思考接口
  • 测试是安全网,使积极重构成为可能
  • 遗留代码 = 没有测试的代码

Martin Fowler(《重构》)

“Kent Beck将先写测试的习惯融入称为测试驱动开发的技术中。”

  • TDD依赖于短周期
  • 测试使重构成为可能
  • 重构变得安全 - 测试即时捕捉回归

反驳点:知道何时打破规则

John Ousterhout(《软件设计哲学》)

“测试驱动开发的问题在于它将注意力集中在让特定功能工作,而不是找到最佳设计。”

当TDD可能有害时:

  • 可能导致战术编程(关注功能,而非设计)
  • 可能产生易于测试但难以理解的代码
  • 过度测试实现细节的风险

平衡:

  • 对于探索性/架构工作,先设计,然后添加测试
  • 不要让测试把你逼入角落
  • 定期退一步评估整体设计

何时使用TDD

使用TDD于:

  • 具有清晰需求的新功能
  • Bug修复(首先编写复制bug的测试)
  • 重构现有代码(首先添加特征化测试)
  • API设计(测试揭示易用性)
  • 任何将长期维护的代码

跳过TDD于:

  • 探索性快速原型(但如果保留代码,之后添加测试)
  • 紧急热修复(但立即之后添加测试)
  • 纯UI/样式更改
  • 一次性脚本
  • 可丢弃原型

TDD工作流

# 1. 编写测试,观察失败
bun test src/thing.test.ts  # RED - 测试失败

# 2. 实现最小代码以通过
bun test src/thing.test.ts  # GREEN - 测试通过

# 3. 重构,测试仍然通过
bun test src/thing.test.ts  # GREEN - 仍然通过

# 4. 重复下一个行为

TDD模式

从断言开始

首先编写断言,然后反向工作:

// 从这里开始
expect(result).toBe(42);

// 然后弄清楚'result'是什么
const result = calculate(input);

// 然后弄清楚'input'是什么
const input = { value: 21 };

三角剖分

使用多个示例驱动泛化:

it("doubles 2", () => expect(double(2)).toBe(4));
it("doubles 3", () => expect(double(3)).toBe(6));
// 现在你必须实现通用解决方案

明显实现

当解决方案明显时,直接编写:

function add(a: number, b: number): number {
  return a + b; // 不要伪装这个
}

假装直到成功

当不确定时,从硬编码值开始:

// 第一遍
function fibonacci(n: number): number {
  return 1; // 对于n=1通过
}

// 为n=2添加测试,然后泛化

测试金字塔

        /\
       /  \     E2E(少数)
      /----\
     /      \   集成测试(一些)
    /--------\
   /          \ 单元测试(多数)
  --------------
  • 单元测试:快速、隔离,测试一件事
  • 集成测试:测试组件交互
  • E2E测试:测试完整用户流程(昂贵,谨慎使用)

常见TDD错误

  1. 一次编写太多测试 - 一次只处理一个失败测试
  2. 测试实现而非行为 - 测试什么,而非如何
  3. 跳过重构步骤 - 技术债务累积
  4. 过度模拟 - 不要模拟你不拥有的东西
  5. 测试私有方法 - 通过公共接口测试

与Beads集成

当处理bead时:

  1. 开始bead:beads_start(id="bd-123")
  2. 为需求编写失败测试
  3. 实现以通过
  4. 重构
  5. 关闭bead:beads_close(id="bd-123", reason="完成:测试通过")