mcpField
T
tdd-workflow

tdd-workflow

github.com/travisjneuman测试与质量106137 次安装今天更新
代码仓库

关于 tdd-workflow

面向明确要求编写测试的开发任务,按 RED-GREEN-REFACTOR 流程指导测试驱动开发,并涵盖测试设计、分类和覆盖率建议。

主要功能

  1. 01RED-GREEN-REFACTOR 循环
  2. 02先写失败测试的指引
  3. 03AAA 测试结构
  4. 04单元、集成与端到端测试指导
  5. 05边界情况和覆盖率建议

适用场景

  1. 01按要求为功能开发编写测试
  2. 02选择合适的单元或集成测试
  3. 03检查边界值与错误情况

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/travisjneuman/.claude --skill tdd-workflow

安装后在 Claude Code 中输入/tdd-workflow确认已加载。

详细介绍

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

仅当用户明确要求编写测试时才使用此技能;否则,通过审查差异和涉及的代码进行验证。

一种严谨的开发方法,让测试驱动设计和实现。

TDD 信条

“不编写失败的测试,就绝不编写一行代码。”

RED-GREEN-REFACTOR 循环

RED 阶段:编写失败的测试

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

规则:

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

示例:

// RED: Test the behavior we want
describe("Calculator", () => {
  it("should add two numbers", () => {
    const calc = new Calculator();
    expect(calc.add(2, 3)).toBe(5);
  });
});

// Run: npm test
// Result: FAIL - Calculator is not defined
// This is RED ✓

检查清单:

  • 已编写测试
  • 运行时测试会失败
  • 失败信息清晰
  • 测试名称描述了预期行为

GREEN 阶段:让测试通过

目标:编写通过测试所需的最少代码。

规则:

  1. 采用能奏效的最简单做法
  2. 不添加额外功能
  3. 不做优化
  4. 只需让测试通过

示例:

// GREEN: Minimum implementation to pass
class Calculator {
  add(a: number, b: number): number {
    return a + b; // Simplest thing that works
  }
}

// Run: npm test
// Result: PASS
// This is GREEN ✓

检查清单:

  • 测试通过
  • 未添加额外代码
  • 实现保持最简

REFACTOR 阶段:改进代码

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

规则:

  1. 只在测试通过时重构
  2. 每次修改后都运行测试
  3. 改进设计,不改变行为
  4. 进行小幅、渐进式修改

重构示例:

  • 提取方法
  • 重命名以提高可读性
  • 删除重复代码
  • 提升性能
  • 添加类型/文档

检查清单:

  • 测试仍然通过
  • 代码更加整洁
  • 行为未发生改变
  • 已准备好进入下一个 RED 阶段

实践 TDD

开始开发新功能
1. Write high-level acceptance test (may not run yet)
2. Write first unit test (RED)
3. Implement minimum code (GREEN)
4. Refactor if needed (REFACTOR)
5. Repeat 2-4 until feature complete
6. Verify acceptance test passes
测试结构(AAA 模式)
it("should [behavior] when [condition]", () => {
  // Arrange - Set up test data and dependencies
  const user = createTestUser({ role: "admin" });
  const service = new UserService();

  // Act - Execute the code under test
  const result = service.getPermissions(user);

  // Assert - Verify expected outcomes
  expect(result).toContain("delete");
  expect(result).toContain("edit");
});
测试命名约定
[Unit]_[Scenario]_[ExpectedResult]

示例:

  • 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% 的覆盖率并不意味着没有 Bug。


快速参考

RED    → Write failing test (define behavior)
GREEN  → Minimum code to pass (make it work)
REFACTOR → Clean up (make it right)
COMMIT → Save progress (make it permanent)

常见的 TDD 错误

错误问题解决方案
测试实现细节测试脆弱测试行为/结果
测试过于庞大难以调试编写更小、更聚焦的测试
共享状态测试不稳定隔离每项测试
测试运行缓慢测试被跳过模拟外部依赖
测试显而易见的代码浪费时间聚焦逻辑

评论

支持 Markdown