bw-mini-app/CLAUDE.md

369 lines
9.0 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.

本文档展示如何在 Claude 环境中严格遵循 **测试驱动开发 (TDD)** 规范。
## 必须使用简体中文(严格遵守)
## 界面(pages/components等)不写测试
## 依赖网络请求、文件请求等外部环境不写测试(mock替代)
## 🎯 TDD 核心原则 (严格遵守)
### 🔴 红阶段:编写失败测试
```typescript
// ❌ 必须先写失败的测试
describe('Calculator', () => {
it('should add two numbers', () => {
const calc = new Calculator(); // 这里会失败 - 正确的!
expect(calc.add(2, 3)).toBe(5);
});
});
```
### 🟢 绿阶段:最小实现
```typescript
// ✅ 只写刚好让测试通过的代码
export class Calculator {
add(a: number, b: number): number {
return a + b; // 最简实现
}
}
```
### 🔄 重构阶段:优化代码
```typescript
// ✅ 在绿灯状态下安全重构
export class Calculator {
/**
* 两数相加
* @param a 第一个数
* @param b 第二个数
* @returns 和
*/
add(a: number, b: number): number {
return a + b;
}
}
```
## 🚫 TDD 强制规则 (绝不违反)
### ❌ 禁止行为
- **绝对不允许**在没有测试的情况下编写生产代码
- **绝对不允许**跳过红阶段直接写实现
- **绝对不允许**在红灯状态下进行重构
- **绝对不允许**同时处理多个失败测试
- **绝对不允许**写example示例代码
- **绝对不允许**业务中写测试代码
- **绝对不允许**业务中写简化或mock代码
### ✅ 必须行为
- **必须切换新分支** 切换新的分支后开始新功能开发
- **必须确认**测试在功能实现前是失败的
- **必须编写**刚好让测试通过的最小代码
- **必须在**所有测试通过的绿灯状态下进行重构
- **必须保持**每个测试的独立性
- **必须遵守**单个文件代码行数不超过500行
- **必须遵守**环境依赖性测试(文件系统监控、网络连接、性能测试),使用模拟对象(Mock)替代真实环境依赖,确保测试的稳定性
## 🛠️ Claude TDD 工作流程
### Step 1: 需求分析 → 测试设计
```bash
# 在 Claude 中的对话流程
用户: "我需要一个计算器功能"
Claude: "让我们从测试开始。首先写一个失败的测试..."
```
### Step 2: 🔴 红阶段执行
```typescript
// 1. 先创建测试文件
// src/calculator.test.ts
import { Calculator } from './calculator'; // ❌ 这会失败
describe('Calculator', () => {
it('should add two positive numbers', () => {
const calculator = new Calculator();
expect(calculator.add(2, 3)).toBe(5);
});
});
```
```bash
# 2. 运行测试确认失败
npm run test
# ❌ Cannot find module './calculator' - 正确的失败!
```
### Step 3: 🟢 绿阶段执行
```typescript
// 3. 创建最小实现
// src/calculator.ts
export class Calculator {
add(a: number, b: number): number {
return a + b; // 最简实现
}
}
```
```bash
# 4. 运行测试确认通过
npm run test
# ✅ Tests: 1 passed, 1 total
```
### Step 4: 🔄 重构阶段执行
```typescript
// 5. 在绿灯状态下改进代码质量
export class Calculator {
/**
* 添加两个数字
* @param a 第一个数字
* @param b 第二个数字
* @returns 两数之和
*/
add(a: number, b: number): number {
// 可以添加输入验证等
if (typeof a !== 'number' || typeof b !== 'number') {
throw new Error('Both arguments must be numbers');
}
return a + b;
}
}
```
```bash
# 6. 确保重构后测试仍然通过
npm run test
# ✅ Tests: 1 passed, 1 total
```
## 📊 Claude TDD 质量检查清单
### 🔴 红阶段检查清单
- [ ] 测试用例清晰表达了期望的行为
- [ ] 测试失败的原因是功能未实现,而非测试错误
- [ ] 测试范围适中,只验证一个具体功能点
- [ ] 测试用例名称具有良好的可读性
### 🟢 绿阶段检查清单
- [ ] 所有测试都通过
- [ ] 实现代码尽可能简单
- [ ] 没有实现当前测试不需要的功能
- [ ] 代码能够正确处理测试用例的所有场景
### 🔄 重构阶段检查清单
- [ ] 消除了代码重复
- [ ] 提高了代码可读性
- [ ] 改善了代码结构
- [ ] 所有测试仍然通过
- [ ] 没有改变外部行为
## 🎓 Claude TDD 最佳实践
### 1. 对话驱动的 TDD
```
用户: "添加减法功能"
Claude: "让我们遵循 TDD 流程:
1. 🔴 先写减法的失败测试
2. 🟢 实现最小的减法功能
3. 🔄 重构优化代码"
```
### 2. 增量式开发
```typescript
// 第一个测试:基本功能
it('should subtract two positive numbers', () => {
expect(calc.subtract(5, 3)).toBe(2);
});
// 第二个测试:边界情况
it('should handle negative results', () => {
expect(calc.subtract(3, 5)).toBe(-2);
});
// 第三个测试:零值处理
it('should handle zero values', () => {
expect(calc.subtract(5, 0)).toBe(5);
});
```
### 3. 测试即文档
```typescript
describe('Calculator', () => {
describe('add method', () => {
it('should add two positive integers correctly', () => {
// 测试名称就是功能文档
});
it('should handle floating point numbers with precision', () => {
// 清晰表达预期行为
});
});
});
```
## 🚀 Claude TDD 命令速查
### 快速启动 TDD 循环
```bash
# 1. 创建测试文件
touch src/feature.test.ts
# 2. 运行测试 (红阶段)
npm run test:watch
# 3. 创建实现文件
touch src/feature.ts
# 4. 运行构建 (绿阶段后)
npm run build
# 5. 查看覆盖率
npm run test:coverage
```
### TDD 开发节奏
```bash
# 保持快速的红-绿-重构循环
🔴 写测试 → ❌ 运行测试 → 🟢 写代码 → ✅ 运行测试 → 🔄 重构 → ✅ 运行测试
```
## 📈 成功的 TDD 指标
### 代码质量指标
-**测试覆盖率**: 95%+ (强制要求)
-**测试执行时间**: < 2 (快速反馈)
- **测试独立性**: 100% (无依赖测试)
- **代码重复度**: 最小化
### TDD 流程指标
- **红-绿-重构循环**: 严格遵循
- **测试先行率**: 100% (无例外)
- **最小实现原则**: 始终遵守
- **重构安全性**: 测试保护下进行
## 🎯 下一步 TDD 开发
继续使用 Claude 进行 TDD 开发时
1. **🔴 红阶段**: 告诉 Claude 你需要什么功能让它先写失败测试
2. **🟢 绿阶段**: Claude 实现最小代码使测试通过
3. **🔄 重构阶段**: Claude 一起改进代码质量
4. **重复循环**: 为每个新功能重复此过程
**记住:在 Claude 环境中TDD 不仅是开发方法,更是确保代码质量和设计优雅的严格纪律!** 🎉
## 💡 Claude TDD 实战示例
### 示例:添加乘法功能
#### 🔴 红阶段:用户请求
```
用户: "我需要添加乘法功能"
Claude: "好的,让我们严格遵循 TDD 流程。首先写一个失败的测试:"
```
#### 测试代码 (先写)
```typescript
// src/calculator.test.ts
describe('Calculator', () => {
// ... 现有测试 ...
describe('multiply', () => {
it('should multiply two positive numbers correctly', () => {
const calculator = new Calculator();
expect(calculator.multiply(3, 4)).toBe(12); // ❌ 这会失败
});
});
});
```
#### 🟢 绿阶段:最小实现
```typescript
// src/calculator.ts
export class Calculator {
add(a: number, b: number): number {
return a + b;
}
multiply(a: number, b: number): number {
return a * b; // 最简实现
}
}
```
#### 🔄 重构阶段:优化代码
```typescript
export class Calculator {
/**
* 两数相加
*/
add(a: number, b: number): number {
return a + b;
}
/**
* 两数相乘
* @param a 被乘数
* @param b 乘数
* @returns 乘积
*/
multiply(a: number, b: number): number {
return a * b;
}
}
```
## 🔧 Claude TDD 故障排除
### 常见问题与解决方案
#### 问题 1: 测试没有失败
```typescript
// ❌ 错误:测试一开始就通过了
it('should return true', () => {
expect(true).toBe(true); // 这不是有效的 TDD 测试
});
// ✅ 正确:测试应该验证具体功能
it('should validate email format', () => {
const validator = new EmailValidator();
expect(validator.isValid('test@example.com')).toBe(true); // 会失败,因为类不存在
});
```
#### 问题 2: 实现过度复杂
```typescript
// ❌ 错误:过度实现
multiply(a: number, b: number): number {
// 不需要的复杂逻辑
if (a === 0 || b === 0) return 0;
if (a === 1) return b;
if (b === 1) return a;
// ... 更多不必要的逻辑
return a * b;
}
// ✅ 正确:最小实现
multiply(a: number, b: number): number {
return a * b; // 简单直接
}
```
#### 问题 3: 在红灯状态下重构
```bash
# ❌ 错误流程
npm run test # ❌ 测试失败
# 开始重构代码 <- 错误!应该先让测试通过
# ✅ 正确流程
npm run test # ❌ 测试失败
# 写最小代码让测试通过
npm run test # ✅ 测试通过
# 现在可以安全重构
```
### 关键文件说明
- `jest.config.js` - 测试框架配置
- `tsconfig.json` - TypeScript 严格模式配置
- `package.json` - TDD 相关脚本命令
- `src/*.test.ts` - 测试文件 (TDD 的核心)