Files
workFlowSkill/dev-tdd/SKILL.md
T
2026-04-27 17:45:20 +08:00

170 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: dev-tdd
description: 开发流程 - TDD 测试先行阶段,基于设计文档生成测试骨架,实现测试驱动开发
---
# TDD 测试先行
> 开发流程第四阶段:基于设计文档生成测试骨架,先写测试再写实现,确保验收标准可量化。
## 调用方式
`/dev-tdd`,也可说"生成测试用例"或"TDD"。
## 产出目录
`docs/test-cases/`(测试用例设计文档)
项目源码中的测试文件(`.test.ts` / `.spec.ts` / `_test.py` 等)
## 执行流程
### Checklist
- [ ] 前置检查:读取需求和设计文档
- [ ] 检测项目测试框架
- [ ] 按模块识别测试点
- [ ] 生成测试用例文档
- [ ] 生成测试代码骨架(空实现 / 先失败)
- [ ] 验证测试可运行且初始状态为失败
- [ ] 用户确认
### 1. 前置检查
- 读取 `docs/requirements/` 需求文档
- 读取 `docs/design/` 设计文档(模块划分、接口定义、数据模型)
- 如果设计文档不存在,提示用户先运行 `/dev-design`(可选择跳过,基于需求直接生成)
- 展示设计摘要,确认测试生成范围
### 2. 检测项目测试框架
自动检测项目使用的测试框架:
| 语言 | 检测方式 | 常用框架 |
|------|---------|---------|
| JavaScript/TypeScript | package.json devDependencies | jest, vitest, mocha, playwright |
| Python | pyproject.toml / requirements.txt | pytest, unittest |
| Java | pom.xml / build.gradle | JUnit, TestNG |
| Go | go.mod | testing, testify |
| Rust | Cargo.toml | 内置 test |
如果没有检测到测试框架:
- 询问用户是否安装(推荐 Vitest 或 Jest 用于 JS/TSpytest 用于 Python
- 如用户拒绝,生成 `docs/test-cases/` 下的纯文本测试用例文档,不生成代码
### 3. 按模块识别测试点
基于设计文档的模块划分,为每个模块识别测试点:
**每个模块的测试点维度:**
- **正常路径**:标准输入下的预期输出
- **边界情况**:空值、最大值、最小值、空数组等
- **错误路径**:异常输入、权限不足、网络失败等
- **状态转换**:涉及状态机的模块,各状态转换路径
### 4. 生成测试用例文档
为每个模块生成测试用例设计文档,保存到 `docs/test-cases/`
```markdown
# 测试用例设计:<模块名>
> 对应设计:docs/design/xxx.md
> 对应模块:模块 A
## 测试用例 1:正常路径 - [简短描述]
**目标**:验证标准场景下的正确行为
**输入**[具体值或描述]
**预期输出**[具体值或描述]
**涉及接口**[函数/端点名]
**优先级**:高
## 测试用例 2:边界情况 - [简短描述]
**目标**:验证边界输入的处理
**输入**[边界值]
**预期输出**[预期行为]
**优先级**:中
## 测试用例 3:错误路径 - [简短描述]
**目标**:验证异常情况的处理
**输入**[异常输入]
**预期输出**[错误码/异常类型]
**优先级**:中
```
### 5. 生成测试代码骨架
基于检测到的测试框架,生成实际的测试代码文件:
**原则:**
- 每个测试用例对应一个测试函数
- 测试函数名清晰描述场景:`should_xxx_when_xxx`
- 导入被测模块(根据设计文档中的接口定义)
- 使用 `todo()``skip()` 标记尚未实现的测试,或先写失败的断言
- 不编写被测模块的实现代码
**示例(Vitest / TypeScript):**
```typescript
// src/modules/user/user.service.test.ts
import { describe, it, expect } from 'vitest'
import { UserService } from './user.service'
describe('UserService', () => {
describe('创建用户', () => {
it('should create user with valid input', () => {
// TODO: 实现测试
// const service = new UserService()
// const result = service.create({ name: '张三', email: 'zs@example.com' })
// expect(result.name).toBe('张三')
expect(true).toBe(false) // 初始状态:失败
})
it('should reject empty name', () => {
// TODO: 实现测试
expect(true).toBe(false) // 初始状态:失败
})
})
})
```
### 6. 验证测试可运行且失败
生成测试后:
- 运行测试框架(如 `npm test` / `pytest`
- 确认测试可以被识别并执行
- 确认测试当前状态为**失败**(红)
- 如测试无法运行,修复配置问题(路径、导入、框架设置等)
### 7. 用户确认
- 展示生成的测试用例文档摘要
- 展示测试代码骨架的关键部分
- 展示测试运行结果(确认是失败的)
- 询问用户是否满意,或需要补充/修改测试场景
- 修改后循环直到确认
## 流转规则
生成完成后,提示下一步:
- `/dev-plan` — 将开发工作拆解为步骤(推荐)
- `/dev-develop` — 直接进入开发,让测试变绿
## 关键行为
- 测试用例必须能追溯到设计文档中的接口定义
- 测试初始状态必须为失败(红),不允许一开始就通过
- 不编写被测模块的实现代码,只写测试
- 测试函数名使用描述性语言,不依赖注释解释场景
- 如果设计文档中的接口不明确,先回到 `/dev-design` 澄清
## TDD 原则提醒
1. **红**:先写一个失败的测试
2. **绿**:写最小代码让测试通过
3. **重构**:优化代码,保持测试通过
本阶段只负责第 1 步(红)。第 2-3 步在 `/dev-develop` 中完成。