Files
workFlowSkill/dev-tdd/SKILL.md
T

170 lines
5.3 KiB
Markdown
Raw Normal View History

2026-04-27 17:45:20 +08:00
---
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` 中完成。