关于 tdd-workflow
这是一套适用于多种语言和测试框架的 TDD 工作流技能,通过失败测试、最小实现、重构及完成检查引导开发,也支持可选的任务跟踪。
主要功能
- 01Red-Green-Refactor 循环
- 02检测语言与测试运行器
- 03增量式测试规划
- 04暂停与继续规则
- 05测试质量与顺序指南
- 06可选任务跟踪集成
适用场景
- 01逐个经过测试的增量开发功能
- 02确认测试因预期原因失败
- 03重构时检查是否引入回归
- 04为现有代码规划测试覆盖
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ majesticlabs-dev/ majestic-marketplace --skill tdd-workflow安装后在 Claude Code 中输入/tdd-workflow确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/increments.mdlanguage-configs.mdrails-tdd-workflow.md详细介绍
TDD 工作流
核心原则
在针对某项行为的失败测试出现之前,绝不编写实现代码。
执行流程
1. 准备
LANG = config_read("tech_stack", "unknown")
If LANG == "unknown": detect from project files (package.json → TypeScript, Gemfile → Ruby, go.mod → Go, pyproject.toml → Python)
If LANG == "unknown": AskUserQuestion("What language/framework?")
RUNNER = lookup LANG in [references/language-configs.md]
If LANG in [ruby]: delegate to `rspec-coder` or `minitest-coder` skill for runner details
INCREMENTS = decompose feature using patterns from [references/increments.md]
- Read requirements/plan
- Identify pattern (Data Transformation, CRUD, State Machine, Calculation, Integration)
- Break into ordered increments: degenerate → happy path → variations → edge cases → errors
For each INCREMENT in INCREMENTS:
TaskCreate(subject: INCREMENT.name, description: INCREMENT.test_description)
AskUserQuestion("Review increments. Adjust ordering or scope?", options: ["Looks good", "Modify"])
2. TDD 循环(逐个增量)
For each INCREMENT in INCREMENTS:
TaskUpdate(INCREMENT.task_id, status: "in_progress")
# RED
Write failing test to real file (not code block)
RUN = Bash(RUNNER.test_command)
If RUN.status == PASS: STOP — investigate unexpected pass
If RUN.status == FAIL (wrong reason): fix test, rerun
PAUSE → show test + failure output, wait for user
# GREEN
Write minimal implementation code
RUN = Bash(RUNNER.full_suite_command)
If RUN.status == FAIL: show output, PAUSE → ask user to fix or hand off
If RUN.status == PASS: auto-continue (no pause)
# REFACTOR
If improvement opportunities exist:
Refactor implementation and/or test code
RUN = Bash(RUNNER.full_suite_command)
If RUN.status == FAIL: revert refactor, PAUSE → discuss
If RUN.status == PASS: auto-continue (no pause)
TaskUpdate(INCREMENT.task_id, status: "completed")
Brief summary of what was implemented
→ immediately begin next increment (no pause between increments)
3. 收尾
RUN = Bash(RUNNER.full_suite_command)
Report: increments completed, total tests, pass/fail status
Suggest: remaining work, missed edge cases, integration tests needed
暂停/继续规则
| 情况 | 操作 |
|---|---|
| RED:测试失败(符合预期) | 暂停 — 展示测试和失败结果,等待用户 |
| RED:测试意外通过 | 停止 — 进行调查,不要继续 |
| GREEN:所有测试通过 | 自动继续到 REFACTOR |
| GREEN:测试失败 | 暂停 — 展示输出并询问用户 |
| REFACTOR:测试通过 | 自动继续到下一个增量 |
| REFACTOR:测试失败 | 还原 + 暂停 — 讨论方案 |
| 增量之间 | 自动继续 — 无需暂停 |
任务跟踪集成
TASK_TRACKING = config_read("task_tracking.enabled", "false")
WORKFLOW_ID = "tdd-{timestamp}"
If TASK_TRACKING:
For each TaskCreate: add metadata {workflow: WORKFLOW_ID, phase: "tdd-loop"}
For each TaskUpdate: wrap with If TASK_TRACKING: TaskUpdate(...)
On Wrap-up: update ledger if LEDGER_ENABLED
LEDGER_ENABLED = config_read("task_tracking.ledger", "false")
LEDGER_PATH = config_read("task_tracking.ledger_path", ".agents/workflow-ledger.yml")
Red-Green-Refactor 循环
1. Red 阶段:编写失败测试
- 从增量中选取一项小而具体的行为
- 编写描述清晰的测试,表达预期行为
- 运行测试,确认其失败(红)
- 失败原因应正确(而非语法错误或缺少依赖)
2. Green 阶段:最小化实现
- 只实现通过失败测试所需的最少代码
- 避免添加额外功能或处理测试尚未覆盖的边界情况
- 运行测试,确认其通过(绿)
3. Refactor 阶段:提升质量
- 检查实现和测试代码,寻找改进之处
- 消除重复、改进命名、提取方法
- 使用特定于语言的惯用写法和模式
- 每次重构后都运行测试,确保测试仍然通过
测试排序策略
按从简单到复杂的顺序编写测试:
- 正常路径 — 使用有效输入验证核心行为
- 验证测试 — 必填字段、格式约束
- 边界情况 — 边界条件、空值、特殊输入
- 错误处理 — 无效输入、失败场景
- 集成点 — 与其他组件的交互
测试质量指南
每项测试都应:
- 只覆盖一项行为
- 保持隔离 — 测试之间不共享状态
- 具有清晰、描述性强的名称
- 只因一个原因而失败
避免:
- 测试实现细节,而非行为
- 在编写代码后再写测试
- 共享会产生隐性依赖的测试准备代码
- 跳过重构阶段
特定于框架的实现
有关特定于语言的测试运行器命令,请参阅 references/language-configs.md。
对于 Ruby 项目:
- **RSpec:**应用
rspec-coderskill - **Minitest:**应用
minitest-coderskill
Rails 示例见 references/rails-tdd-workflow.md。
测试生成模式
在 TDD 循环之外编写测试时(例如,为现有代码增加覆盖率),请遵循以下模式。
框架检测
| 依据 | 框架 |
|---|---|
spec/ + _spec.rb + .rspec | RSpec |
test/ + _test.rb + test_helper.rb | Minitest |
*.test.js + jest.config.js | Jest |
tests/ 或 e2e/ 中的 *.spec.ts | Playwright |
vitest.config.js | Vitest |
测试计划结构
编写测试前,先制定计划,涵盖:
- 范围 - 要测试哪些功能
- 正常路径场景 - 预期成功的流程
- 异常路径场景 - 错误处理、验证、失败
- 边界情况 - 边界条件、空值、特殊输入
- 授权检查 - 授权/身份验证(如适用)
- 测试数据要求 - 所需的固定数据或数据
- 模拟策略 - 要模拟的外部服务/依赖
测试用例矩阵
适用于包含多个参数的复杂场景:
| 目标 | 输入 | 预期输出 | 测试类型 |
|---|---|---|---|
| 验证创建 | 有效参数 | 已创建,201 | 正向路径 |
| 拒绝重复项 | 已存在的数据 | 错误,422 | 反向路径 |
| 处理空值 | 缺少字段 | 验证错误 | 边界情况 |
完成标准
满足以下所有条件后,测试才算完成:
覆盖率: 测试所有公开方法,覆盖正向、反向和边界路径,并包含身份验证检查。
质量: 测试通过(已实际运行验证)、相互隔离(无共享状态)、遵循 AAA 模式(准备-执行-断言),且名称清晰。
框架合规性: 使用恰当的匹配器和模拟,遵循项目模式。
编写测试的最佳实践
- 测试行为,而非实现细节
- 每个测试聚焦于一个断言
- 使用清晰的测试名称,说明预期行为
- 优先使用显式断言,而非隐式断言
- 谨慎且有目的地使用测试替身
- 使用 describe/context 块对相关测试进行分组
- 测试数据应尽量精简,但足以满足需求
- 对于 Rails:使用事务性夹具和 database cleaner
- 对于 Playwright:采用恰当的等待策略,避免不稳定的选择器
评论
支持 Markdown