🧪 测试金字塔
测试金字塔是测试策略的经典模型。根据 Google 测试博客,理想比例是:70% 单元测试、20% 集成测试、10% E2E 测试。
E2E 测试(10%)
真实浏览器、完整流程
集成测试(20%)
API、组件交互
单元测试(70%)
函数、组件、模块
| 测试类型 | 速度 | 成本 | 可靠性 | 调试难度 |
|---|---|---|---|---|
| 单元测试 | 快(毫秒) | 低 | 高(隔离) | 易 |
| 集成测试 | 中(秒级) | 中 | 中 | 中 |
| E2E 测试 | 慢(分钟级) | 高 | 低(脆弱) | 难 |
💡 独特观点
单元测试的真正价值不是"发现错误",而是驱动设计。TDD(测试驱动开发)让你先想清楚接口,再写实现,产出更优质的代码。
🧪 单元测试核心
单元测试是最小可测试单元(函数、组件、模块)的验证。核心是 AAA 模式:Arrange(准备)、Act(执行)、Assert(断言)。
1. AAA 模式(Arrange-Act-Assert)
📝 AAA 模式示例(Jest)
// 测试函数:计算购物车总价
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
// ✅ 好的单元测试(AAA 模式)
describe('calculateTotal', () => {
test('应正确计算购物车总价', () => {
// 1. Arrange(准备):创建测试数据
const items = [
{ name: '商品A', price: 100, quantity: 2 },
{ name: '商品B', price: 50, quantity: 1 },
];
// 2. Act(执行):调用被测函数
const result = calculateTotal(items);
// 3. Assert(断言):验证结果
expect(result).toBe(250); // 100*2 + 50*1 = 250
});
test('空购物车应返回 0', () => {
// Arrange
const items = [];
// Act
const result = calculateTotal(items);
// Assert
expect(result).toBe(0);
});
});2. 测试覆盖率(Coverage)
覆盖率指标:
语句覆盖率(Statement)
每行代码是否执行到
function abs(x) {
if (x >= 0) { // ① 需要测试 x >= 0
return x; // ② 需要测试 x >= 0
} else {
return -x; // ③ 需要测试 x < 0
}
}分支覆盖率(Branch)
每个 if/else 分支是否覆盖
// 需要两个测试用例:
// 1. x >= 0 → 走 if 分支
// 2. x < 0 → 走 else 分支函数覆盖率(Function)
每个函数是否调用到
行覆盖率(Line)
每一行是否执行(类似语句覆盖)
📝 生成覆盖率报告(Jest)
// jest.config.js
module.exports = {
collectCoverage: true,
collectCoverageFrom: [
'src/**/*.{js,jsx}',
'!src/index.js',
'!src/**/*.stories.js',
],
coverageReporters: ['text', 'lcov', 'html'],
coverageThreshold: {
global: {
statements: 80,
branches: 80,
functions: 80,
lines: 80,
},
},
};
// 运行测试并生成报告
// npx jest --coverage
//
// 输出:
// ----------|---------|----------|---------|---------
// File | % Stmts | % Branch | % Funcs | % Lines
// ----------|---------|----------|---------|---------
// All files | 85.42 | 78.95 | 81.82 | 85.42
// utils.js | 85.42 | 78.95 | 81.82 | 85.42
// ----------|---------|----------|---------|---------📝 总结与展望
单元测试是保障代码质量的基石。通过本文的学习,你应该掌握了:
🎯 核心要点
- 测试金字塔:70% 单元测试、20% 集成测试、10% E2E 测试
- AAA 模式:Arrange(准备)、Act(执行)、Assert(断言)
- Jest:Describe、test、expect、Matcher、Hook
- Vitest:Vite 生态、ESM 支持、更快的执行速度
- Testing Library:以用户为中心、避免测试实现细节
- Mock/Stub:jest.mock()、vi.mock()、依赖隔离
- 覆盖率:语句、分支、函数、行覆盖率
- React 测试:RTL(render、fireEvent、waitFor)
- Vue 测试:VTU(mount、wrapper、trigger)
- CI/CD 集成:GitHub Actions、自动运行测试、覆盖率报告
🚀 未来展望
测试领域正在快速演进,值得关注的方向:
- Visual Regression Testing:截图对比(Percy、Chromatic)
- AI 生成测试:GitHub Copilot、GPT-4 生成测试用例
- Property-Based Testing:基于属性的测试(fast-check)
- Contract Testing:消费者驱动的合同测试(Pact)
- Shadow Testing:生产环境并行测试(流量复制)