name: 测试策略 description: 选择和实施测试方法的战略指导,涵盖测试金字塔中的单元、集成、端到端和契约测试。适用于构建全面的测试套件,平衡速度和信心,涵盖多语言模式(TypeScript、Python、Go、Rust)和现代最佳实践,包括属性测试、测试数据管理和CI/CD集成。
测试策略
通过战略性地选择和实施单元、集成、端到端和契约测试级别的正确测试方法,构建全面、有效的测试套件。
目的
此技能提供战略框架:
- 测试类型选择:确定何时使用单元测试、集成测试、端到端测试或契约测试
- 测试金字塔平衡:优化测试分布,以实现快速反馈和可靠覆盖
- 多语言实施:在TypeScript、Python、Go和Rust中应用一致的测试模式
- 测试数据管理:选择适当的策略(固定数据、工厂生成、属性测试)
- CI/CD集成:将测试集成到自动化管道中,具有最佳执行模式
测试是可靠软件的基础。随着微服务架构和持续交付在2025年成为标准,跨多个级别的战略测试比以往任何时候都更加关键。
何时使用此技能
在以下情况下调用此技能:
- 构建需要测试覆盖的新功能
- 为新项目设计测试策略
- 重构现有测试以提高速度或可靠性
- 设置包含测试阶段的CI/CD管道
- 在单元、集成或端到端测试方法之间选择
- 为微服务实施契约测试
- 使用固定数据、工厂生成或属性测试管理测试数据
测试金字塔框架
核心概念
测试金字塔指导测试分布,以实现最佳速度和信心:
/\
/ \ 端到端测试 (10%)
/----\ - 慢但全面
/ \ - 全栈验证
/--------\
/ \ 集成测试 (20-30%)
/ \ - 中等速度
/--------------\ - 组件交互
/ \
/------------------\ 单元测试 (60-70%)
- 快速反馈
- 隔离单元
关键原则:更多单元测试(快速、隔离),更少端到端测试(慢、全面)。集成测试桥接差距。
现代适应(2025)
微服务调整:
- 在单元和集成之间添加契约测试层
- 增加集成/契约测试至30%(验证服务边界)
- 仅保留关键用户旅程的端到端测试
云原生模式:
- 使用容器进行集成测试(临时数据库、测试服务)
- 并行执行以获取快速CI/CD反馈
- 基于风险的测试优先级(关注高影响区域)
有关详细金字塔指导,请参见references/testing-pyramid.md。
通用测试决策树
应该使用哪种测试类型?
开始:需要测试[功能]
问题1:这涉及多个系统/服务吗?
├─ 是 → 问题2
└─ 否 → 问题3
问题2:这是一个关键的用户面向工作流吗?
├─ 是 → 端到端测试(完整用户旅程)
└─ 否 → 集成或契约测试
问题3:这与外部分依赖(数据库、API、文件系统)交互吗?
├─ 是 → 集成测试(真实数据库、模拟API)
└─ 否 → 问题4
问题4:这是纯业务逻辑或纯函数吗?
├─ 是 → 单元测试(快速、隔离)
└─ 否 → 组件或集成测试
测试类型选择示例
| 功能 | 测试类型 | 理由 |
|---|---|---|
calculateTotal(items) |
单元测试 | 纯函数,无依赖 |
POST /api/users 端点 |
集成测试 | 测试API + 数据库交互 |
| 用户注册流程(表单 → API → 重定向) | 端到端测试 | 关键用户旅程,全栈 |
| 微服务A → B通信 | 契约测试 | 服务接口验证 |
formatCurrency(amount, locale) |
单元测试 + 属性测试 | 纯逻辑,许多边缘情况 |
| 表单验证逻辑 | 单元测试 | 隔离业务规则 |
| 文件上传到S3 | 集成测试 | 外部服务交互 |
有关综合决策框架,请参见references/decision-tree.md。
测试级别详细说明
单元测试(基础 - 60-70%)
目的:验证小型、隔离的代码单元(函数、方法、组件)
特点:
- 快速(每个测试毫秒级)
- 隔离(无外部依赖)
- 确定性(相同输入 = 相同输出)
- 广泛覆盖(许多测试,每个小范围)
何时使用:
- 纯函数(输入 → 输出)
- 业务逻辑和算法
- 工具函数
- 组件渲染(无集成)
- 验证逻辑
推荐工具:
- TypeScript/JavaScript:Vitest(主要,比Jest快10倍),Jest(传统)
- Python:pytest(行业标准)
- Go:测试包(标准库)+ testify(断言)
- Rust:cargo test(标准库)
有关详细模式,请参见references/unit-testing-patterns.md。
集成测试(中间层 - 20-30%)
目的:验证组件、模块或服务之间的交互
特点:
- 中等速度(每个测试秒级)
- 部分集成(真实数据库,模拟外部API)
- 专注范围(测试组件边界)
- API和数据库验证
何时使用:
- API端点(请求 → 响应)
- 数据库操作(CRUD、查询)
- 服务间通信
- 事件处理程序和消息处理
- 文件I/O操作
推荐工具:
- TypeScript/JavaScript:Vitest + MSW(API模拟),Supertest(HTTP测试)
- Python:pytest + pytest-httpserver,pytest-postgresql
- Go:测试 + httptest,testcontainers
- Rust:cargo test + mockito,testcontainers
有关详细模式,请参见references/integration-testing-patterns.md。
端到端测试(顶层 - 10%)
目的:验证整个应用程序栈的完整用户工作流
特点:
- 慢(每分钟测试套件)
- 完全集成(真实浏览器、服务、数据库)
- 宽范围(从开始到结束的用户旅程)
- 易出现不稳定(需要仔细设计)
何时使用:
- 关键用户旅程(登录、结账、支付)
- 跨浏览器兼容性验证
- 集成测试未覆盖的真实世界场景
- 核心功能的回归预防
最佳实践:
- 限制端到端测试于高价值场景(非每个边缘情况)
- 使用稳定选择器(data-testid,非CSS类)
- 实施网络不稳定性的重试逻辑
- 并行运行测试以提高速度
推荐工具:
- 所有语言:Playwright(跨浏览器、快速、微软支持)
有关详细模式,请参见references/e2e-testing-patterns.md。
契约测试(微服务)
目的:验证服务接口和API契约,无需完全集成
何时使用:
- 微服务架构
- 服务间通信
- API契约验证
- 减少端到端测试开销
推荐工具:Pact(pact.io) - 支持TypeScript、Python、Go、Rust
有关详细模式,请参见references/contract-testing.md。
测试数据管理策略
何时使用每种方法
固定数据(静态数据):
- 优点:确定性,易于调试
- 缺点:可能过时,不测试多样性
- 使用时机:测试已知场景,回归测试
工厂生成(生成数据):
- 优点:灵活,生成多样性
- 缺点:确定性较差,更难调试
- 使用时机:需要多样测试数据,测试边缘情况
属性测试(随机数据):
- 优点:发现未预期的边缘情况
- 缺点:可能慢,失败更难复现
- 使用时机:复杂算法、解析器、验证器
推荐组合:
- 单元测试:固定数据(已知输入)+ 属性测试(边缘情况)
- 集成测试:工厂生成(灵活数据)+ 数据库播种
- 端到端测试:固定数据(可复现场景)
属性测试工具:
- TypeScript/JavaScript:fast-check
- Python:hypothesis(最佳类)
- Go:gopter
- Rust:proptest(主要)
有关详细策略,请参见references/test-data-strategies.md。
模拟决策矩阵
何时模拟 vs. 使用真实依赖
| 依赖 | 单元测试 | 集成测试 | 端到端测试 |
|---|---|---|---|
| 数据库 | 模拟(内存中) | 真实(测试数据库、Docker) | 真实(暂存数据库) |
| 外部API | 模拟(MSW、nock) | 模拟(MSW、VCR) | 真实(或暂存) |
| 文件系统 | 模拟(内存中文件系统) | 真实(临时目录) | 真实 |
| 时间/日期 | 模拟(freezeTime) | 模拟(如果确定性) | 真实(通常) |
| 环境变量 | 模拟(setEnv) | 模拟(测试配置) | 真实(测试环境) |
| 内部服务 | 模拟(存根) | 真实(或容器) | 真实 |
指导原则:
- 单元测试:模拟所有外部内容
- 集成测试:使用真实数据库(临时),模拟外部API
- 端到端测试:使用所有真实内容(或暂存等效)
- 契约测试:不模拟(测试真实接口)
有关详细模拟模式,请参见references/mocking-strategies.md。
语言特定快速入门
TypeScript/JavaScript
使用Vitest进行单元测试:
import { describe, test, expect } from 'vitest'
test('计算含税总额', () => {
const items = [{ price: 10, quantity: 2 }]
expect(calculateTotal(items, 0.1)).toBe(22)
})
使用MSW进行集成测试:
import { setupServer } from 'msw/node'
import { http, HttpResponse } from 'msw'
const server = setupServer(
http.get('/api/user/:id', ({ params }) => {
return HttpResponse.json({ id: params.id, name: '测试用户' })
})
)
使用Playwright进行端到端测试:
import { test, expect } from '@playwright/test'
test('用户可以结账', async ({ page }) => {
await page.goto('https://example.com')
await page.getByRole('button', { name: '添加到购物车' }).click()
await expect(page.getByText('购物车中有1件商品')).toBeVisible()
})
请参见examples/typescript/获取完整工作示例。
Python
使用pytest进行单元测试:
def test_calculate_total_with_tax():
items = [{"price": 10, "quantity": 2}]
assert calculate_total(items, tax_rate=0.1) == 22
使用hypothesis进行属性测试:
from hypothesis import given, strategies as st
@given(st.lists(st.integers()))
def test_reverse_reverse_is_identity(lst):
assert reverse(reverse(lst)) == lst
请参见examples/python/获取完整工作示例。
Go和Rust
请参见examples/go/和examples/rust/获取这些语言的完整工作示例。
覆盖和质量指标
有意义的覆盖目标
推荐目标:
- 关键业务逻辑:90%+ 覆盖
- API端点:80%+ 覆盖
- 工具函数:70%+ 覆盖
- UI组件:60%+ 覆盖(关注逻辑,非标记)
- 整体项目:70-80% 覆盖
反模式:追求100%覆盖导致测试琐碎代码和虚假信心。
覆盖工具:
- TypeScript/JavaScript:Vitest覆盖(c8/istanbul)
- Python:pytest-cov
- Go:go test -cover
- Rust:cargo-tarpaulin
突变测试(验证测试质量)
突变测试引入错误并验证测试能捕获它们。
工具:
- TypeScript/JavaScript:Stryker Mutator
- Python:mutmut
- Go:go-mutesting
- Rust:cargo-mutants
有关详细覆盖策略,请参见references/coverage-strategies.md。
CI/CD集成模式
快速反馈循环策略
阶段1:提交前(< 30秒)
- Lint和格式化检查
- 单元测试(仅关键路径)
阶段2:提交时(< 2分钟)
- 所有单元测试
- 静态分析
阶段3:拉取请求(< 5分钟)
- 集成测试
- 覆盖报告
阶段4:合并前(< 10分钟)
- 端到端测试(关键路径)
- 跨浏览器测试
并行执行
加速测试运行:
- Vitest:
vitest --threads - Playwright:
playwright test --workers=4 - pytest:
pytest -n auto(需要pytest-xdist) - Go:
go test -parallel 4
常见反模式避免
冰激凌锥(倒金字塔)
问题:太多端到端测试,太少单元测试 结果:慢测试套件、不稳定测试、长反馈循环 解决方案:重新平衡向更多单元测试,更少端到端测试
测试实现细节
问题:测试耦合到内部结构,非行为 解决方案:测试行为(输入 → 输出),非实现
集成测试中过度模拟
问题:模拟一切违背集成测试目的 解决方案:使用真实数据库(临时),仅模拟外部API
不稳定端到端测试
问题:由于时序问题,测试间歇性失败 解决方案:
- 使用自动等待功能(Playwright有内置自动等待)
- 避免硬编码等待(
sleep(1000)) - 使用稳定选择器(data-testid)
- 为网络请求实施重试逻辑
与其他技能集成
对于表单测试:请参见building-forms技能以获取表单特定验证和提交测试模式。
对于API测试:请参见api-patterns技能以获取REST/GraphQL端点测试和契约验证。
对于CI/CD管道:请参见building-ci-pipelines技能以获取测试自动化、并行执行和覆盖报告。
对于数据可视化测试:请参见visualizing-data技能以获取快照测试图表配置和视觉回归测试。
参考文档
有关特定主题的深入探索:
references/testing-pyramid.md- 详细测试金字塔框架和平衡策略references/decision-tree.md- 测试类型选择的综合决策框架references/unit-testing-patterns.md- 跨语言的单元测试模式references/integration-testing-patterns.md- 与数据库、API和容器的集成测试references/e2e-testing-patterns.md- 端到端测试最佳实践和Playwright模式references/contract-testing.md- 使用Pact的消费者驱动契约测试references/test-data-strategies.md- 固定数据、工厂生成和属性测试references/mocking-strategies.md- 何时及如何模拟依赖references/coverage-strategies.md- 有意义的覆盖指标和突变测试
工作示例
完整、可运行代码示例可在examples/目录中找到:
examples/typescript/- Vitest单元/集成测试、Playwright端到端测试、MSW模拟、fast-check属性测试examples/python/- pytest单元/集成测试、固定数据、Playwright端到端测试、hypothesis属性测试examples/go/- 标准库测试、testify断言、httptest集成测试examples/rust/- cargo test单元测试、proptest属性测试、集成模式
所有示例包括依赖项、使用说明和错误处理。