Testing Strategies 是一份关于测试策略、模式与方法论的技能文档,覆盖从单元测试到端到端测试的完整测试谱系。
用途 该文档用于在讨论单元测试、集成测试、端到端测试、测试金字塔等话题时提供参考,帮助开发者与团队建立或改进测试体系。
主要能力
- 测试金字塔:单元测试约占 65-80%,集成测试约占 15-25%,端到端测试约占 5-10%。单元测试快速(毫秒级),隔离测试单个函数或类;集成测试验证组件协同工作,如服务调用数据库、模块交互、HTTP 处理器处理请求;端到端测试模拟真实用户行为,慢且维护成本高、易不稳定,仅用于关键用户旅程。倒置金字塔会导致反馈慢、CI 不稳定、调试困难。
- 单元测试模式:Arrange-Act-Assert(AAA)与 Given-When-Then(BDD 术语,等价于 AAA)。若测试名包含“and”,可能测试了过多内容。
- Mocking 策略:测试替身类型包括 Stub(返回预定数据)、Spy(记录调用)、Mock(预编程期望)、Fake(可工作的简化实现,如内存数据库)。当依赖慢、不确定、有副作用或需模拟错误时应 Mock;当协作者是值对象、测试集成本身、Mock 复制依赖逻辑或 Mock 三层深时不应 Mock。过度 Mock 会让测试通过而真实系统已损坏。
- 集成测试:数据库测试应使用真实数据库而非 Mock,每个测试后回滚事务或使用全新 schema 隔离。Testcontainers 可在 Docker 中启动真实服务(PostgreSQL、Redis、Kafka),支持 Java、Python、Node.js、Go、.NET。API 集成测试使用运行中的服务器与真实或容器化依赖,验证响应与持久化状态。
- 端到端测试:测试关键用户旅程(注册、结账、支付、核心工作流),不用于低层可覆盖的边界情况。Playwright 支持多浏览器(Chromium、Firefox、WebKit)、多语言、多标签与 iframe,适合跨浏览器与复杂场景;Cypress 仅 JavaScript、主要基于 Chromium,DX 强、支持时间旅行调试,适合纯 JS 团队与较简单需求。选择器应使用 data-testid,不要用 CSS 类或 DOM 结构。
- 测试驱动开发:Red-Green-Refactor。Red 为下一小段行为写失败测试;Green 写最少代码通过;Refactor 在测试保持绿色时清理。先选最简单行为,写一个测试,运行并确认因正确原因失败,写刚好足够的代码,确认通过,必要时重构,重复。
- 基于属性的测试:生成数百个随机输入并检查不变量。可捕获边界 off-by-one、Unicode 处理失败、整数溢出、罕见输入组合。Python 使用 hypothesis,JavaScript 使用 fast-check。适用于纯函数、序列化往返、数据转换与有明确不变量的函数。
- 快照测试:适用于捕获序列化输出(HTML、JSON、CLI 输出)的意外变化、保护生成代码;有害于无人审查的大快照、每次有意变更都破坏导致盲目 --update、易变数据(时间戳、随机 ID)快照。快照应保持小,超过 30-40 行应改为断言特定字段。
- 测试覆盖率:行覆盖率衡量执行而非验证,100% 覆盖率无断言毫无意义。应关注分支覆盖率、行为覆盖率与关键路径覆盖率。80% 行覆盖率是合理下限。变异测试通过修改生产代码(> 改 >=、删除行、交换布尔值)检查测试是否失败,存活变异体表示测试不足。工具:Stryker(JS/TS)、PIT(Java)、mutmut(Python)、cargo-mutants(Rust)。高变异分数比高行覆盖率是更强的质量信号。
- API 测试:Pact 契约测试验证消费者与提供者对 API 形状达成一致,无需两个服务同时运行;消费者生成契约文件,提供者独立验证。Schema 校验在测试中依据 OpenAPI/JSON Schema 验证响应,捕获文档与实际行为漂移。
- 性能测试:k6 负载测试,测量响应时间百分位(p50、p95、p99)而非平均值,跟踪吞吐量、负载下错误率与资源消耗。k6 可脚本化且 CI 友好;Artillery 使用 YAML 配置,适合快速 HTTP/WebSocket 负载测试。
- CI/CD 中的测试:使用 jest --shard、pytest-split 或 CI 原生并行(GitHub Actions matrix、CircleCI)拆分测试,按时间数据分配防止慢分片瓶颈。不稳定测试应隔离到非阻塞任务,跟踪 flake 率(BuildPulse、Datadog Test Visibility),在定义 SLA 内修复或删除,不要将重试并忽略作为永久方案。
- 测试命名规范:测试名应读作行为规格,如 [unit][scenario][expected result]、should [behavior] when [condition]、given [context] when [action] then [outcome]。名称应无需阅读测试体即可知道失败内容。
- 测试数据管理:工厂生成带合理默认值的对象并允许覆盖特定字段,使用 factory_boy(Python)、FactoryBot(Ruby)、Fishery(TypeScript)。构建器通过链式方法调用提供细粒度控制。夹具提供共享设置数据,应保持最小,大型共享夹具会造成隐藏耦合。优先使用工厂而非夹具。
- 反模式:测试实现细节、脆弱选择器、慢速套件、Mock 一切、共享可变状态、忽视维护。
- 不应测试的内容:无逻辑的 getter、setter、构造函数;框架内部(ORM SQL 生成、路由分发、React 渲染);第三方库;常量。每个测试都应通过捕获真实类别的 bug 来证明其存在价值。
使用方式 该文档为技能参考文档,通过阅读与查阅方式使用,未提供安装命令或代码运行方式。
适用场景 适用于需要建立或改进测试体系的开发者与团队,包括单元测试、集成测试、端到端测试、TDD、性能测试、契约测试、CI/CD 测试管理等场景。
限制 该文档为方法论与模式参考,未提供具体产品的收费、价格、平台或效果信息。