第二章 测试策略设计:测试金字塔模型、分层测试策略、冒烟测试与回归测试、测试覆盖率定义
大家好,我是老张。今天咱们聊聊测试策略设计。说实话,我见过太多团队一上来就写自动化脚本,结果越写越乱,最后连自己都搞不清在测什么。为什么会这样?说白了,就是缺少一个清晰的测试策略。
我个人习惯,在开始任何自动化工作之前,先画一张测试策略图。这张图的核心,就是今天要讲的四个东西:测试金字塔、分层策略、冒烟与回归、覆盖率定义。
2.1 测试金字塔模型
测试金字塔这个概念,最早是Mike Cohn提出来的。我刚开始接触时觉得这玩意儿太理论了,直到有一次在一个大型ERP项目上栽了跟头——我们写了上千个端到端测试,每次跑都要好几个小时,而且一改需求就全崩。嗯,从那以后我才真正理解金字塔的价值。
金字塔分三层:
- 底层:单元测试 —— 测单个函数、单个模块。跑得快,几分钟搞定。
- 中间层:服务测试 —— 测接口、API、服务间的交互。比单元测试慢一点,但还算可控。
- 顶层:UI测试 —— 模拟用户操作,点按钮、填表单。最慢,也最脆弱。
你想想看,如果金字塔倒过来,顶层UI测试最多,底层单元测试最少,会怎样?我经历过,每次跑完一轮测试,光等结果就要喝三杯咖啡。而且UI稍微动一下,脚本就废了。
核心原则:底层测试要多,顶层测试要少。比例大概在 70% 单元测试、20% 服务测试、10% UI测试。
我记得有一次给一个金融项目做咨询,他们非要反着来。我说这样不行,他们不信。结果上线前一周,一个底层逻辑改了,UI测试全红,但单元测试覆盖率太低,根本定位不到问题。最后加班三天才搞定。从那以后,他们再也不敢忽视金字塔了。
2.2 分层测试策略
金字塔是理论,分层策略是落地。说白了,就是每一层测什么、怎么测、谁来测。
| 层级 | 测试对象 | 工具推荐 | 执行频率 |
|---|---|---|---|
| 单元测试 | 函数、方法、类 | JUnit, pytest, Jest | 每次提交 |
| 服务测试 | API、微服务接口 | Postman, REST Assured | 每日构建 |
| UI测试 | 用户界面、流程 | Selenium, Cypress | 关键版本 |
我在项目中遇到过一种情况:单元测试和服务测试都过了,但UI测试还是挂了。为什么?因为前端和后端的数据格式对不上。所以分层不是孤立的,每一层之间要有衔接。
我的小技巧:在服务测试层,我会加一些契约测试。比如用Pact工具,提前约定好接口的输入输出格式。这样前后端各自开发,最后联调时问题少很多。
另外,分层策略还要考虑环境。单元测试可以在本地跑,服务测试需要测试环境,UI测试最好用独立的 staging 环境。我曾经因为环境混用,导致测试结果一直不稳定,排查了两天才发现是数据污染。嗯,这个坑你们别踩。
2.3 冒烟测试与回归测试
这两个概念经常被混淆。我简单解释一下:
- 冒烟测试: 检查系统最核心的功能能不能跑通。比如登录、创建订单、支付。如果冒烟都过不了,后面的测试就别做了。
- 回归测试: 改完代码后,重新跑一遍所有测试,确保没引入新问题。
我个人习惯,冒烟测试一定要快。控制在5分钟以内。如果超过10分钟,那就不是冒烟了,是烤全羊。
避坑指南:我曾经在一个项目上,把冒烟测试写成了全量回归测试,每次跑40分钟。结果开发提交代码后,等冒烟结果就要等半天,效率极低。后来我把冒烟测试精简到10个核心用例,5分钟跑完,团队效率直接翻倍。
回归测试呢?我建议分两种:
- 全量回归: 大版本发布前做,覆盖所有功能。
- 增量回归: 小改动时做,只测受影响的部分。
怎么判断哪些是受影响的部分?我一般用代码覆盖率工具来辅助。比如改了A模块,那所有调用A模块的测试都要跑一遍。这个后面会细说。
2.4 测试覆盖率定义
覆盖率这个词,很多人一听就觉得越高越好。其实不然。我见过一个团队,把覆盖率目标定到100%,结果测试代码比业务代码还多,维护成本高得吓人。
覆盖率分几种:
| 类型 | 定义 | 我的建议 |
|---|---|---|
| 行覆盖率 | 代码中每一行是否被执行过 | 目标 80% 以上 |
| 分支覆盖率 | if/else 等分支是否都覆盖到 | 目标 70% 以上 |
| 函数覆盖率 | 每个函数是否被调用过 | 目标 90% 以上 |
| 路径覆盖率 | 所有可能的执行路径 | 看情况,一般不做硬性要求 |
我个人最看重分支覆盖率。为什么?因为很多bug都藏在分支逻辑里。比如一个if条件写反了,行覆盖率可能显示100%,但分支覆盖率会告诉你某个分支没走到。
举个例子:
def calculate_discount(amount, is_vip):
if is_vip:
return amount * 0.8
else:
return amount * 0.9
如果测试只传了 is_vip=True,行覆盖率是100%,但分支覆盖率只有50%。因为 else 分支根本没测到。这种bug上线后才发现,那就尴尬了。
我记得有一次做支付系统的测试,行覆盖率95%,但上线后还是出了事故。查下来发现,是一个异常处理分支没覆盖到。从那以后,我就把分支覆盖率作为硬性指标了。
工具推荐:Java项目用JaCoCo,Python用coverage.py,前端用Istanbul。这些工具都能生成覆盖率报告,还能和CI集成。
最后说一句,覆盖率不是万能的。它只能告诉你哪些代码被测试过,不能告诉你测试的质量如何。我见过有人为了凑覆盖率,写一堆没意义的测试用例。比如测一个getter方法,这有什么意义呢?所以,覆盖率要结合测试用例的设计一起看。
好了,这一章就到这里。下一章我们聊聊测试用例设计方法,包括等价类划分、边界值分析这些实战技巧。到时候我会分享一些我在金融项目中的真实案例,保证干货满满。