测试驱动开发Skill tdd-workflow

测试驱动开发(TDD)是一种软件开发实践,通过先编写测试用例来定义需求,然后实现代码使测试通过,最后重构代码以提高质量。它采用RED-GREEN-REFACTOR循环,确保代码可测试、可维护,并提高开发效率和测试覆盖率。关键词:测试驱动开发、TDD、RED-GREEN-REFACTOR、单元测试、自动化测试、代码质量、软件测试、敏捷开发、测试优先。

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

name: tdd-workflow description: 测试驱动开发工作流强制执行,采用RED-GREEN-REFACTOR周期。用于在实现功能时测试优先或提高测试覆盖率。

测试驱动开发(TDD)工作流

一种纪律严明的开发方法,测试驱动设计和实现。

TDD 箴言

“永远不要在没有失败测试的情况下写一行代码。”

RED-GREEN-REFACTOR 循环

RED 阶段:写一个失败的测试

目标:在实现之前定义预期行为。

规则

  1. 写一个最小的失败测试
  2. 测试必须因正确原因失败
  3. 测试应清晰地表达意图
  4. 不要写实现代码

示例

// RED:测试我们想要的行为
describe("Calculator", () => {
  it("should add two numbers", () => {
    const calc = new Calculator();
    expect(calc.add(2, 3)).toBe(5);
  });
});

// 运行:npm test
// 结果:失败 - Calculator 未定义
// 这是 RED ✓

检查清单

  • [ ] 测试已写
  • [ ] 测试运行失败
  • [ ] 失败信息清晰
  • [ ] 测试名称描述预期行为

GREEN 阶段:使测试通过

目标:写最少的代码使测试通过。

规则

  1. 做最简单可行的事
  2. 不要添加额外功能
  3. 不要优化
  4. 只让它变绿

示例

// GREEN:通过测试的最小实现
class Calculator {
  add(a: number, b: number): number {
    return a + b; // 最简单可行的事
  }
}

// 运行:npm test
// 结果:通过
// 这是 GREEN ✓

检查清单

  • [ ] 测试通过
  • [ ] 未添加额外代码
  • [ ] 实现是最小的

REFACTOR 阶段:改进代码

目标:清理代码,同时保持测试通过。

规则

  1. 只在测试通过时重构
  2. 每次更改后运行测试
  3. 改进设计,而不是行为
  4. 小步、增量更改

重构示例

  • 提取方法
  • 重命名以提高清晰度
  • 去除重复
  • 提高性能
  • 添加类型/文档

检查清单

  • [ ] 测试仍然通过
  • [ ] 代码更整洁
  • [ ] 行为未改变
  • [ ] 准备好下一个 RED

TDD 实践

开始新功能

1. 写高层次验收测试(可能尚未运行)
2. 写第一个单元测试(RED)
3. 实现最小代码(GREEN)
4. 如果需要,重构(REFACTOR)
5. 重复 2-4 直到功能完成
6. 验证验收测试通过

测试结构(AAA 模式)

it("should [行为] when [条件]", () => {
  // Arrange - 设置测试数据和依赖
  const user = createTestUser({ role: "admin" });
  const service = new UserService();

  // Act - 执行被测试代码
  const result = service.getPermissions(user);

  // Assert - 验证预期结果
  expect(result).toContain("delete");
  expect(result).toContain("edit");
});

测试命名约定

[单元]_[场景]_[预期结果]

示例:

  • add_withPositiveNumbers_returnsSum
  • login_withInvalidPassword_throwsAuthError
  • getUser_whenNotFound_returnsNull

测试类别

单元测试

  • 单个函数/类在隔离环境中
  • 模拟所有依赖
  • 快速(<10ms 每个测试)
  • 在开发期间持续运行

集成测试

  • 多个组件一起
  • 真实数据库(测试实例)
  • 较慢但更现实
  • 提交前运行

端到端测试

  • 通过UI的完整系统
  • 最慢,最现实
  • 在CI/CD管道中运行
  • 覆盖关键用户路径

TDD 最佳实践

要做:

  • 从最简单情况开始
  • 一次写一个测试
  • 保持测试独立
  • 测试行为,而不是实现
  • 使用描述性测试名称
  • 每次变绿后提交

不要做:

  • 在测试前写代码
  • 直接测试私有方法
  • 测试框架代码
  • 过度适应测试到实现
  • 跳过重构阶段

要测试的边缘情况

始终测试:

  • 空输入(null, undefined, [], {}, ‘’)
  • 边界值(0, -1, MAX_INT, 最小/最大日期)
  • 错误条件(网络失败,无效输入)
  • 权限边界
  • 并发访问
  • Unicode/特殊字符

测试覆盖率指南

指标 最低 目标
语句覆盖率 70% 85%
分支覆盖率 70% 80%
函数覆盖率 80% 90%
行覆盖率 70% 85%

覆盖率是指标,不是目标。100% 覆盖率不意味着无错误。


快速参考

RED    → 写失败测试(定义行为)
GREEN  → 最少代码通过(让它工作)
REFACTOR → 清理代码(让它正确)
COMMIT → 保存进度(让它永久)

常见 TDD 错误

错误 问题 解决方案
测试实现 脆弱测试 测试行为/结果
测试太大 难以调试 更小、专注的测试
共享状态 不稳定测试 隔离每个测试
慢测试 被跳过的测试 模拟外部依赖
测试明显代码 浪费时间 专注于逻辑