- Add depthGuard agent for depth-limiting sub-agent orchestration - Update strictPlan/strictSpec agents with improved task handling - Refresh builtin skill registry - Update builtInAgents with depthGuard integration - Add nested-agent design docs and user guide - Update README_EN with project documentation
246 lines
6.0 KiB
Markdown
246 lines
6.0 KiB
Markdown
# TDD Skill (L1/L2)
|
||
|
||
## 概述
|
||
测试驱动开发(TDD):RED → GREEN → REFACTOR 循环
|
||
|
||
## 深度状态
|
||
- **当前深度**: L1 或 L2 (根据调用上下文)
|
||
- **最大深度**: 2
|
||
- **可spawn**: 无 (叶子节点)
|
||
|
||
## TDD三阶段
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ TDD循环 │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │
|
||
│ │ RED │ ──→ │ GREEN │ ──→ │ REFACTOR │ │
|
||
│ │ 写测试 │ │ 写实现 │ │ 重构优化 │ │
|
||
│ │ 测试失败 │ │ 测试通过 │ │ 覆盖率检查 │ │
|
||
│ └─────────┘ └─────────┘ └─────────────┘ │
|
||
│ │ │ │ │
|
||
│ └───────────────┴──────────────────┘ │
|
||
│ ↓ │
|
||
│ ┌─────────────────┐ │
|
||
│ │ 下一测试用例 │ │
|
||
│ └─────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Phase 1: RED (失败测试)
|
||
|
||
### 任务
|
||
编写测试代码,测试必须失败(因为实现还不存在)
|
||
|
||
### 规则
|
||
|
||
### ✅ 必须
|
||
- 为每个功能点编写完整测试
|
||
- 使用describe/test/it结构
|
||
- 包含Arrange-Act-Assert模式
|
||
- 设置正确的expected值
|
||
- Mock外部依赖
|
||
|
||
### ❌ 禁止
|
||
- 不要写任何实现代码
|
||
- 不要尝试让测试通过
|
||
- 不要跳过任何测试用例
|
||
|
||
### 输出
|
||
```json
|
||
{
|
||
"phase": "RED",
|
||
"test_files": [
|
||
{
|
||
"path": "src/__tests__/auth.login.test.ts",
|
||
"content": "import { describe, test, expect } from 'vitest'..."
|
||
}
|
||
],
|
||
"expected_failures": ["TC001", "TC002", "TC003"],
|
||
"run_command": "bun test src/__tests__/auth.login.test.ts"
|
||
}
|
||
```
|
||
|
||
## Phase 2: GREEN (通过实现)
|
||
|
||
### 任务
|
||
编写最小实现代码,让所有测试通过
|
||
|
||
### 规则
|
||
|
||
### ✅ 必须
|
||
- 编写最小化实现
|
||
- 让所有RED阶段的测试通过
|
||
- 不写多余代码 (YAGNI原则)
|
||
- 保持代码简洁
|
||
|
||
### ❌ 禁止
|
||
- 不要跳过任何测试
|
||
- 不要写未来可能用到的代码
|
||
- 不要过度设计
|
||
|
||
### 输出
|
||
```json
|
||
{
|
||
"phase": "GREEN",
|
||
"implementation_files": [
|
||
{
|
||
"path": "src/services/auth.service.ts",
|
||
"changes": {"additions": 30, "deletions": 0}
|
||
}
|
||
],
|
||
"test_results": {
|
||
"total": 3,
|
||
"passed": 3,
|
||
"failed": 0
|
||
}
|
||
}
|
||
```
|
||
|
||
## Phase 3: REFACTOR (重构优化)
|
||
|
||
### 任务
|
||
优化代码结构,保持测试通过
|
||
|
||
### 规则
|
||
|
||
### ✅ 必须
|
||
- 优化代码结构和命名
|
||
- 消除重复代码
|
||
- 提高可读性
|
||
- 保持所有测试通过
|
||
|
||
### ❌ 禁止
|
||
- 不要添加新功能
|
||
- 不要破坏现有测试
|
||
- 不要降低覆盖率
|
||
|
||
### 覆盖率要求
|
||
- 行覆盖率 >= 80%
|
||
- 分支覆盖率 >= 75%
|
||
- 函数覆盖率 >= 90%
|
||
|
||
### 输出
|
||
```json
|
||
{
|
||
"phase": "REFACTOR",
|
||
"refactored_files": [
|
||
{
|
||
"path": "src/services/auth.service.ts",
|
||
"improvements": ["提取validateToken函数", "简化错误处理"]
|
||
}
|
||
],
|
||
"coverage": {
|
||
"lines": 85,
|
||
"branches": 78,
|
||
"functions": 92
|
||
},
|
||
"test_results": {
|
||
"total": 3,
|
||
"passed": 3,
|
||
"failed": 0
|
||
}
|
||
}
|
||
```
|
||
|
||
## Mock使用
|
||
|
||
### Vitest Mock模板
|
||
|
||
```typescript
|
||
import { vi } from 'vitest'
|
||
|
||
// 模块Mock
|
||
vi.mock('../services/apiClient', () => ({
|
||
fetch: vi.fn().mockResolvedValue({ data: 'mocked' })
|
||
}))
|
||
|
||
// 函数Mock
|
||
const mockFn = vi.fn()
|
||
.mockReturnValue('result')
|
||
.mockResolvedValue('async result')
|
||
.mockRejectedValue(new Error('error'))
|
||
```
|
||
|
||
### Mock验证
|
||
|
||
```typescript
|
||
// 验证调用
|
||
expect(mockFn).toHaveBeenCalled()
|
||
expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2')
|
||
expect(mockFn).toHaveBeenCalledTimes(1)
|
||
|
||
// 验证调用顺序
|
||
expect(mockFn.mock.calls).toEqual([
|
||
['call1'],
|
||
['call2']
|
||
])
|
||
```
|
||
|
||
## 完整输出格式
|
||
|
||
```json
|
||
{
|
||
"tdd_id": "tdd_xxx",
|
||
"status": "completed",
|
||
"phases": {
|
||
"red": {
|
||
"tests_written": 5,
|
||
"test_files": ["test1.ts", "test2.ts"],
|
||
"expected_failures": 5
|
||
},
|
||
"green": {
|
||
"implementation_files": ["service.ts"],
|
||
"tests_passed": 5,
|
||
"tests_failed": 0
|
||
},
|
||
"refactor": {
|
||
"files_refactored": 2,
|
||
"improvements": ["提取公共函数", "简化逻辑"]
|
||
}
|
||
},
|
||
"coverage": {
|
||
"lines": 85,
|
||
"branches": 78,
|
||
"functions": 92
|
||
},
|
||
"verdict": "PASS",
|
||
"total_duration_ms": 5000
|
||
}
|
||
```
|
||
|
||
## 错误处理
|
||
|
||
### RED阶段测试通过
|
||
```json
|
||
{
|
||
"error": "TDD_VIOLATION",
|
||
"message": "Test passed in RED phase - tests must fail before implementation",
|
||
"violated_tests": ["TC001"],
|
||
"suggestion": "Remove implementation or fix test expectation"
|
||
}
|
||
```
|
||
|
||
### GREEN阶段测试失败
|
||
```json
|
||
{
|
||
"error": "IMPLEMENTATION_INCOMPLETE",
|
||
"message": "Tests failed after implementation",
|
||
"failed_tests": ["TC002"],
|
||
"suggestion": "Complete implementation for failing test cases"
|
||
}
|
||
```
|
||
|
||
### 覆盖率不达标
|
||
```json
|
||
{
|
||
"error": "COVERAGE_BELOW_THRESHOLD",
|
||
"current": {"lines": 65, "branches": 60},
|
||
"required": {"lines": 80, "branches": 75},
|
||
"suggestion": "Add more test cases for uncovered branches"
|
||
}
|
||
```
|