📚单元测试
✅ 核心原则 (F.I.R.S.T)
-
Fast (快速)
- 使用内存数据库替代真实DB
- 避免IO操作
-
Independent (独立)
- 测试间不应存在依赖
- 每个测试前重置状态
-
Repeatable (可重复)
- 固定随机种子
- Mock外部依赖
-
Self-Validating (自验证)
- 断言必须明确
- 避免手动验证结果
-
Timely (及时)
- 测试与生产代码同步编写
🔧 测试代码规范
命名规范 (类/方法/变量)
// 三段式命名
[被测对象]_[测试条件]_[预期结果]
void transferMoney_withInsuffientBalance_throwsException()
断言规范
// 坏
expect(result).toBeTruthy();
// 好
expect(result).toEqual({
status: 'SUCCESS',
transactionId: expect.any(String)
});
🚨 常见反模式
| 问题类型 | 示例 | 修复方案 |
|---|---|---|
| 复杂Fixture | 50行setup代码 | 使用Builder模式 |
| 过度断言 | assert(result.x && result.y) | 拆分多个测试 |
| 脆弱测试 | 依赖特定日期 | Mock时间 |
⚡️ 现代测试实践
Visual Testing
# Storybook + Chromatic
npx chromatic --storybook-build-dir=build
Mutation Testing
// 原代码
return a > 0 ? a : -a;
// 突变测试
return a < 0 ? a : -a; # 好的测试应能捕获此错误
🛠️ 推荐工具链
- Java: ArchUnit (架构测试)
- JavaScript: Testing Library
- All: Jest/Playwright (快照测试)
💡 关键摘要
"脏测试比没测试更危险,因为它提供虚假的安全感"
"测试代码应该是生产代码的最佳文档"