170 lines
5.3 KiB
Markdown
170 lines
5.3 KiB
Markdown
---
|
||
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/TS,pytest 用于 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` 中完成。
|