3. 测试脚本设计:业务场景建模、请求参数化、断言与检查点、事务控制器与思考时间设置
脚本设计这事儿,说白了就是把你对业务的理解,翻译成工具能听懂的语言。我见过太多人一上来就录脚本,录完就跑,结果压出来的数据跟线上差了十万八千里。嗯,今天咱们就把这四块掰开揉碎了讲。
3.1 业务场景建模:别让脚本骗了你
场景建模是脚本设计的灵魂。你想想看,线上用户是随机点来点去,还是按固定流程走?大部分业务都有明确的业务路径。
我个人习惯,先画业务流程图,再转成脚本结构。举个例子,电商下单流程:
- 用户浏览商品列表
- 查看商品详情
- 加入购物车
- 提交订单
- 支付
这五个步骤,每一步都有不同的请求类型和参数。你不能只压一个「下单」接口,那测的是接口性能,不是业务吞吐。
核心原则:场景建模要覆盖 80% 的日常流量路径,再加 20% 的异常或边界场景。我在项目中遇到过,只压主路径,结果大促时「查看详情」这个环节先挂了,因为图片加载没做优化。
这里有个避坑指南:不要用录制功能直接生成脚本。录制出来的脚本通常包含大量冗余请求(CSS、JS、图片),这些在吞吐测试里会严重干扰结果。我建议手动构建请求,只保留业务核心的 API 调用。
3.2 请求参数化:让数据活起来
参数化是脚本设计里最容易偷懒、也最容易出问题的地方。你想想看,如果 1000 个并发用户都用同一个账号、买同一个商品,那测出来的吞吐量能信吗?
参数化的本质是模拟真实用户的数据多样性。常见的参数化方式有:
| 参数化方式 | 适用场景 | 注意事项 |
|---|---|---|
| CSV 数据文件 | 用户账号、商品 ID、订单号 | 注意数据量要足够,避免循环使用 |
| 函数生成 | 时间戳、随机字符串、UUID | 确保唯一性,避免冲突 |
| 数据库查询 | 从已有数据中动态获取 | 注意数据库连接池压力 |
| 计数器 | 递增序列号 | 多线程下要保证原子性 |
我个人最常用的是 CSV + 函数生成组合。比如用户登录,用 CSV 文件提供 10000 个账号;每次请求的时间戳用函数生成,确保每次都不一样。
小技巧:参数化数据要提前做「数据预热」。我曾经遇到过,压测跑到一半,数据库里没有对应的商品 ID 了,结果全是 404 响应,吞吐量曲线直接断崖下跌。排查了半天才发现是参数化数据没准备好。
3.3 断言与检查点:别让错误数据污染结果
断言和检查点,很多人觉得是「锦上添花」的东西。其实恰恰相反,它们是吞吐测试的守门员。
为什么这么说?你压了 10000 个请求,工具告诉你平均响应时间 200ms,吞吐量 5000 TPS。但如果你没加断言,这 10000 个请求里可能有 3000 个是返回了错误码的。错误请求的响应时间通常很短(比如 400 或 500 错误),它们会拉低平均响应时间,虚高吞吐量。这数据你敢信?
我建议至少设置以下检查点:
- HTTP 状态码检查:200、201、302 等,排除 4xx/5xx
- 响应体关键字段检查:比如
success: true或code: 0 - 响应时间阈值检查:超过某个阈值(比如 5s)直接标记为失败
警告:不要只检查状态码。我遇到过接口返回 200,但 body 里是 {"error": "timeout"}。如果只看状态码,这些错误请求会被当成成功,你的吞吐量数据就全废了。
代码示例(JMeter 风格):
// 响应断言配置
响应字段:响应文本
模式匹配:包含
测试模式:"success": true
// 持续时间断言
响应时间阈值:5000ms
如果超过,标记为失败
3.4 事务控制器与思考时间:还原真实用户行为
事务控制器和思考时间,是脚本设计里最容易被忽略、也最能影响结果真实性的两个设置。
3.4.1 事务控制器:把多个请求打包成一个「业务操作」
事务控制器的作用,是把多个请求合并成一个逻辑事务。比如「用户下单」这个事务,包含了浏览、加购、提交、支付四个请求。如果你单独看每个请求的响应时间,看不出整体体验。但用事务控制器包裹后,你能看到整个下单流程的总耗时。
我个人习惯,在以下场景必须使用事务控制器:
- 有前后依赖关系的请求链(比如登录 → 获取 token → 调用业务接口)
- 需要统计端到端响应时间的业务路径
- 需要保证原子性的操作(要么全部成功,要么全部失败)
注意:事务控制器会增加内存开销。如果脚本里有几百个事务,建议先做小规模验证,看看会不会 OOM。我在项目中遇到过,事务嵌套太多,压测机自己先挂了。
3.4.2 思考时间:别让服务器「空转」
思考时间模拟的是用户阅读页面、输入信息、犹豫不决的时间。没有思考时间的脚本,相当于让用户以机器速度疯狂点击,这测的是极限压力,不是真实吞吐。
思考时间的设置原则:
| 业务类型 | 建议思考时间 | 说明 |
|---|---|---|
| 浏览类(查看列表、详情) | 3-10 秒 | 用户需要阅读内容 |
| 操作类(填写表单、提交) | 5-15 秒 | 用户需要输入信息 |
| 支付类 | 2-5 秒 | 支付流程通常较快 |
| API 对 API(无界面) | 0-1 秒 | 系统间调用,几乎无等待 |
这里有个坑:思考时间不要用固定值。真实用户的操作间隔是随机的。我建议用随机函数,比如 Random(3000, 8000) 毫秒,模拟 3 到 8 秒的随机等待。
避坑指南:我曾经做过一个金融项目,脚本里没加思考时间,压出来的 TPS 是线上的 5 倍。业务方看了数据说「你们测的是机器人吧?」后来加了符合业务场景的思考时间,TPS 降到了线上的 1.2 倍,这才对得上。所以,思考时间不是用来「作弊」降低吞吐的,而是用来还原真实负载的。
3.5 本章知识体系总览
下面这张图,把脚本设计的四个核心模块串起来了。你可以把它当成一个检查清单,每次设计脚本时对照着过一遍。