测试作为设计工具 = 先写测试就是先想清楚 API
解决什么问题:测试沦为验证工具,难以推行—— 测试的真正价值是设计工具。先写测试 = 先想清楚 API。
业务问题
真实场景
场景 1:测试 = 验证工具的反模式
团队反模式:
- 先写代码
- 再补测试("为了让 CI 绿")
- 测试是负担
- 测试覆盖低
- 重构恐惧
结果:
- 测试质量差(只是"运行通过")
- 不敢重构(测试脆弱)
- bug 多场景 2:测试 = 设计工具的正模式
团队正模式:
- 先写测试(TDD)
- 测试 = API 设计的"第一次调用"
- 测试 = 文档(可执行)
- 测试 = 重构保障
结果:
- API 易用(测试就是 caller)
- 重构有信心
- bug 少失败模式
| 失败模式 | 后果 |
|---|---|
| 后补测试 | 测试脆弱、只是"运行通过" |
| 测试实现 | 重构就坏 |
| Mock 一切 | 测试与生产脱节 |
| 大测试覆盖广 | 慢、脆弱、难调试 |
控制论视角
Ch 4 §4.6:"控制律的可验证性" + Ch 6 §6.7:"可重复性"
测试 = Ch 4 §4.6 可验证性
- 控制律(代码)必须可被验证
- 测试 = 验证的具体形式
- 测试先行 = 设计阶段的验证
测试 = Ch 6 §6.7 可重复性
- 控制律输出必须可重复
- 测试 = 可重复的具体形式核心概念
测试的 4 个价值(按重要性)
1. 设计工具(最重要)
- 先写测试 = 强迫设计 API
- 测试 = API 的第一次 caller
- 好的测试 = 好的设计
2. 文档(可执行)
- 测试 = 用代码写的"如何使用"
- 比注释更可靠(不会过期)
3. 重构保护
- 改代码 → 测试保证不破坏
- 改设计 → 测试保证行为不变
4. 抓 bug(最少价值)
- 测试覆盖率 ≠ 无 bug
- 但显著减少 bugGoogle 的 Small/Medium/Large
Small Tests:
- 单一进程
- 无网络 / 文件系统
- 无 sleep
- < 100ms
Medium Tests:
- 单机
- localhost 网络可用
- < 1s
Large Tests:
- 多机
- 真实集成
- 秒级以上测试金字塔(Google 版)
/ E2E \ ← 10%:关键路径
/ 集成 \ ← 20%:服务间协作
/ Small \ ← 70%:单元 + 小集成工程实践
决策 1:测试覆盖率目标
不追求 100%(不可能也不必要)
追求 80%+(关键路径全覆盖)
"关键路径"定义:
- 业务核心逻辑
- 公开 API
- 数据持久化
- 安全相关决策 2:测试 = 文档策略
原则:
- 测试名 = 文档标题
- 测试结构 = AAA(Arrange-Act-Assert)
- 测试名 = 业务语言(不是技术语言)
例(反模式):
def test_order_creation_with_valid_input():
# 业务名 = 技术名 ✓ 但不够具体
例(正模式):
def test_creating_an_order_with_out_of_stock_item_fails():
# 业务名 = 完整场景 ✓实战 1:测试驱动设计的 4 步
Step 1:写失败的测试(Red)
- 测试调用还不存在的 API
- 强迫想清楚:API 长什么样?
Step 2:让测试通过(Green)
- 写最简单的实现
- 不追求优雅
Step 3:重构(Refactor)
- 优化设计
- 测试保护下重构
Step 4:扩展(Repeat)
- 下一个场景反模式 vs 正模式
| 反模式 | 正模式 |
|---|---|
| 后补测试 | TDD / 测试先行 |
| 测试实现细节 | 测试行为 |
| Mock 一切 | 用真实对象(必要时 mock) |
| 大测试覆盖广 | 小测试覆盖广 |
| 100% 覆盖 | 80%+ 关键路径 |
性能指标
| 指标 | 衡量 | 健康值 |
|---|---|---|
| 测试覆盖率 | 关键路径覆盖率 | > 80% |
| 测试大小比例 | Small : Medium : Large | 70 : 20 : 10 |
| 测试运行时间 | 全套测试时间 | < 10min |
| 测试稳定性 | flaky 率 | < 1% |
边界判断
何时用 TDD
- 业务核心
- 公开 API
- 复杂逻辑
- 易出 bug 的地方
何时不用 TDD
- 一次性脚本
- 实验代码
- UI 原型
- 简单的 CRUD
何时升级
| 当前 | 升级到 | 触发条件 |
|---|---|---|
| 后补测试 | 测试先行 | 设计质量差 |
| 大量大测试 | 测试金字塔 | 跑得慢 |
| 测试实现 | 测试行为 | 重构频繁 |
关键洞察
- 测试 = 设计工具——最大价值是先想清楚 API。
- 小测试 = 大信心——70% small 是 Google 数据支撑。
- 测试是文档——可执行、永不过期。
- TDD 不仅是方法——它是设计的纪律。
- 与 cybernetics 同构——Ch 4 §4.6 可验证 = 测试 = 控制律的验证机制。