name: test-pyramid-design description: 设计最优的测试金字塔,包括单元/集成/E2E测试的比例。识别反模式并推荐特定架构的测试策略。 allowed-tools: Read, Write, Glob, Grep, Task, WebSearch, WebFetch
测试金字塔设计
何时使用此技能
在以下情况下使用此技能:
- 测试金字塔设计任务 - 在设计最优的测试金字塔,包括单元/集成/E2E测试的比例时。识别反模式并推荐特定架构的测试策略
- 规划或设计 - 需要关于测试金字塔设计方法的指导
- 最佳实践 - 希望遵循既定的模式和标准
概述
测试金字塔由Mike Cohn引入,可视化测试在不同级别上的理想分布。底部是更细粒度的测试(快速、廉价),顶部是较少的广泛测试(缓慢、昂贵)。
经典测试金字塔
┌───────┐
/ E2E \ ~10%
/ Tests \ (UI, Acceptance)
/─────────────\
/ Integration \ ~20%
/ Tests \ (API, Component)
/───────────────────\
/ Unit Tests \ ~70%
/ (Fast, Cheap) \ (Methods, Classes)
└─────────────────────────┘
测试级别特征
| 级别 | 速度 | 成本 | 范围 | 置信度 | 维护性 |
|---|---|---|---|---|---|
| 单元 | 最快(毫秒) | 最低 | 单个单元 | 低 | 低 |
| 集成 | 中等(秒) | 中等 | 组件 | 中 | 中 |
| E2E | 最慢(分钟) | 最高 | 完整系统 | 高 | 高 |
常见金字塔形状
健康金字塔 ✅
/\ 单元: 70%+
/ \ 集成: 20%
/ \ E2E: 10%
/ \
/________\ 快速反馈,低维护
特征:
- 快速CI/CD流水线
- 快速反馈循环
- 低不稳定性
- 易于维护
冰激凌筒 ❌
██████████ E2E: 60%
████████ 集成: 30%
████ 单元: 10%
问题:
- 缓慢流水线(小时)
- 不稳定测试
- 昂贵维护
- 延迟反馈
修复:提取单元测试,减少E2E范围
纸杯蛋糕 ❌
██████████ E2E: 40%
██████████ 手动: 50%
████ 单元: 10%
问题:
- 高手动测试成本
- 不一致覆盖
- 慢发布周期
修复:自动化关键路径,添加集成层
沙漏 ❌
██ E2E: 10%
██████████ 集成: 70%
██ 单元: 20%
问题:
- 缓慢集成测试
- 脆性测试夹具
- 缺失单元测试覆盖
修复:将覆盖推至单元级别
架构特定金字塔
单体应用
/\ 单元: 70%
/ \ 集成: 20%
/ \ E2E: 10%
/______\
专注于业务逻辑的单元测试。
微服务
/\ E2E/契约: 10%
/ \ 集成: 30%
/ \ 单元: 60%
/______\
更多集成测试用于服务边界。 添加服务间契约测试。
事件驱动架构
/\ E2E: 10%
/ \ 集成: 35%
/ \ 单元: 55%
/______\
集成测试用于事件处理器。 单元测试用于事件处理逻辑。
前端重度(SPA)
/\ E2E: 15%
/ \ 集成: 25%
/ \ 单元/组件: 60%
/______\
组件测试替代部分单元测试。 集成级别进行视觉回归测试。
测试奖杯(Kent C. Dodds)
前端应用替代方案:
┌─────┐
│ E2E │ ~5%
┌──┴─────┴──┐
│集成│ ~50%
┌──┴───────────┴──┐
│ 静态 │ ~10%
┌──┴─────────────────┴──┐
│ 单元 │ ~35%
└────────────────────────┘
设计你的金字塔
步骤1:评估当前状态
按级别计数测试:
级别 | 数量 | 总百分比 | 时间 | 通过率
-------------|-------|---------|---------|----------
E2E | 150 | 45% | 30 分钟 | 85%
集成 | 100 | 30% | 10 分钟 | 95%
单元 | 80 | 25% | 30 秒 | 99%
步骤2:识别反模式
| 如果你有… | 形状 | 优先级修复 |
|---|---|---|
| E2E > 30% | 冰激凌筒 | 提取至更低级别 |
| 单元 < 50% | 倒置 | 为逻辑添加单元测试 |
| 集成 > 50% | 沙漏 | 推至单元级别 |
| 手动 > 20% | 纸杯蛋糕 | 自动化关键路径 |
步骤3:设置目标比例
基于架构:
| 架构 | 单元 | 集成 | E2E |
|---|---|---|---|
| 单体 | 70% | 20% | 10% |
| 微服务 | 60% | 30% | 10% |
| 无服务器 | 50% | 40% | 10% |
| 前端 SPA | 40% | 45% | 15% |
步骤4:迁移计划
按ROI优先:
- 快速胜利:转换不稳定E2E为集成
- 覆盖缺口:为关键逻辑添加单元测试
- 契约测试:添加服务边界
- 移除重复:合并冗余E2E测试
测试级别指南
单元测试
应测试:
- 业务逻辑
- 算法
- 数据转换
- 验证规则
- 边缘情况
不应测试:
- 外部服务
- 数据库查询
- 文件系统操作
- 第三方库
集成测试
应测试:
- 数据库存储库操作
- API端点
- 消息处理器
- 外部服务适配器
- 组件交互
不应测试:
- 纯业务逻辑(使用单元测试)
- 完整用户旅程(使用E2E)
E2E测试
应测试:
- 关键用户旅程
- 快乐路径
- 冒烟测试
- 跨系统工作流
不应测试:
- 边缘情况(使用单元测试)
- API契约(使用集成测试)
- 所有内容(有选择性)
.NET示例:测试项目结构
src/
MyApp.Domain/ # 业务逻辑
MyApp.Application/ # 用例
MyApp.Infrastructure/ # 数据访问
MyApp.Api/ # HTTP端点
tests/
MyApp.Domain.Tests/ # 单元测试 (70%)
Features/
Orders/
CreateOrderTests.cs
OrderValidationTests.cs
MyApp.Application.Tests/ # 集成测试 (20%)
Features/
Orders/
CreateOrderHandlerTests.cs
MyApp.Api.Tests/ # E2E测试 (10%)
Features/
Orders/
OrdersEndpointTests.cs
测试分布验证
// 构建脚本或CI检查
public class TestDistributionTests
{
[Fact]
public void TestPyramidRatiosAreHealthy()
{
var unitTests = CountTestsInAssembly("MyApp.Domain.Tests");
var integrationTests = CountTestsInAssembly("MyApp.Application.Tests");
var e2eTests = CountTestsInAssembly("MyApp.Api.Tests");
var total = unitTests + integrationTests + e2eTests;
Assert.True(unitTests / total >= 0.60, "单元测试应 ≥60%");
Assert.True(e2eTests / total <= 0.15, "E2E测试应 ≤15%");
}
}
指标与监控
流水线健康
| 指标 | 健康 | 警告 | 严重 |
|---|---|---|---|
| 单元测试时间 | < 1 分钟 | 1-5 分钟 | > 5 分钟 |
| 集成测试时间 | < 5 分钟 | 5-15 分钟 | > 15 分钟 |
| E2E测试时间 | < 10 分钟 | 10-30 分钟 | > 30 分钟 |
| 不稳定测试率 | < 1% | 1-5% | > 5% |
覆盖平衡
按金字塔级别跟踪覆盖:
- 业务逻辑单元覆盖:≥90%
- API集成覆盖:≥80%
- 关键路径E2E覆盖:100%
集成点
输入来自:
- 架构文档 → 金字塔形状
- 风险评估 → E2E范围
输出至:
test-strategy-planning技能 → 策略文档- CI/CD 配置 → 流水线阶段
automation-strategy技能 → 自动化范围