Skip to content
返回质量保障

测试金字塔

平衡测试套件:大量快单元测试,较少集成,极少端到端。

为什么

测试金字塔是按速度和信心分配测试精力的启发式。底——大量单元测试——秒级跑、抓大多回归、给精确失败位置。中——集成测试——分钟级跑、抓接缝 bug。顶——少量 E2E——数十分钟跑、抓断旅程变更但 flaky 且慢。倒金字塔团队(少单元多 E2E)终得 40 分钟 flaky 套件,难调试,没人本地跑。金字塔保持快反馈环快,把慢贵测试留给值得的少数旅程。

何时使用

从项目开始就把金字塔当套件形状目标,周期性审计实际形状。若 E2E 套件增长快于单元套件,在反馈环退化前再平衡。

如何做

1. 测当前套件形状
   - 按类型数测试: 单元、集成、E2E
   - 测每类型运行时间: 单元(<10s)、集成(<5min)、E2E(<20min)
   - 画金字塔: 若 e2e > integration > unit,你倒置了

2. 设目标比例(经典金字塔)
   - 单元: 70% 测试,<10s 总运行
   - 集成: 20% 测试,<5min 总
   - E2E: 10% 测试(3-15 条),<20min 总
   - 按上下文调: UI 重应用可能 E2E 多,库几乎没有

3. 尽可能把测试下推
   - 查表单验证的 E2E → 移到验证器的单元测试
   - 查纯变换的集成 → 移到单元测试
   - 测试越低反馈越快越精确

4. CI 中门控套件形状
   - e2e 数超阈值(如 20)无审查即失败
   - 变更文件单元覆盖低于 60% 警告
   - 追踪套件运行时间作指标;每季涨 > 20% 即查

5. 每季重审再平衡
   - 找可下推的测试(测逻辑非旅程的 E2E)
   - 删不守卫的测试(被测代码已删)
   - 保持快环快——这是金字塔的全部意义

示例

# 审计脚本: 按类型数测试并测运行时间
# scripts/audit-pyramid.sh
echo "=== 测试金字塔审计 ==="
echo "单元测试:       $(find src -name '*.test.ts' | wc -l)"
echo "集成测试:       $(find tests/integration -name '*.test.ts' | wc -l)"
echo "E2E 测试:        $(find e2e -name '*.spec.ts' | wc -l)"

echo ""
echo "=== 运行时间 ==="
time vitest run --reporter=dot 2>&1 | tail -1   # 单元
time vitest run --config vitest.integration.ts 2>&1 | tail -1  # 集成
time npx playwright test 2>&1 | tail -1  # E2E

# 样本输出:
# 单元测试:       342
# 集成测试:       48
# E2E 测试:        12
# 比例: 85% / 12% / 3%——健康金字塔,快反馈环完好。

# 倒金字塔(坏):
# 单元测试:        18
# 集成测试:       24
# E2E 测试:       156
# 比例: 9% / 12% / 79%——40 分钟套件,没人本地跑,回归溜进。

常见问题

  • ⚠倒金字塔(多 E2E 少单元)给 40 分钟 flaky 不精确套件——E2E 挂时根因可能在栈任何处,调试要数小时非数秒。
  • ⚠"冰淇淋锥"(多手动、些 E2E、少单元)靠人抓回归,不扩展——团队长测试面长,手动覆盖必落后。
  • ⚠把金字塔当刚性规则而非启发式导致把测试强塞错层——薄 UI 库可能合理地主要用 E2E/视觉测试,那没问题。
  • ⚠只测测试数不测运行时间藏了真问题——100 条各 2 分钟的单元测试(因打数据库)比 20 条各 30 秒的 E2E 更糟。

最佳实践

  • ✓同时追踪每层测试数和运行时间——金字塔关于快反馈,70/20/10 中 70% 跑 5 分钟不是健康金字塔。
  • ✓每当测试慢或 flaky,问"能下推一层吗?"——大多测逻辑的 E2E 可成剥 UI 的同逻辑单元测试。
  • ✓每季审计金字塔形状并设预算:如"单元套件须低于 10s,E2E 低于 20 条"——CI 中超限警告或失败。
  • ✓按上下文调金字塔:后端微服务可能钻石形(多集成、些单元、少 E2E),对接缝重架构那是对的。