3. 测试脚本设计:业务场景建模、参数化与数据驱动、关联与断言、事务控制与思考时间

脚本设计这事儿,说白了就是把你对业务的理解,翻译成机器能跑的语言。我见过太多人一上来就录脚本,录完就跑,结果压测数据跟实际业务差了十万八千里。嗯,这一章咱们就聊聊怎么把脚本写“对”。

核心观点:脚本不是录出来的,是设计出来的。每一个参数、每一个断言、每一个思考时间,背后都应该有业务逻辑支撑。

3.1 业务场景建模:别让脚本脱离真实

场景建模是脚本设计的起点。你想想看,用户真的会像你录脚本那样,机械地点击吗?不会。用户的行为是有路径、有分支、有思考的。

我个人习惯把业务场景拆成三层:

  • 主路径场景:用户最常走的流程,比如“登录→搜索→加购→下单→支付”。这是压测的基线。
  • 分支路径场景:用户可能走的其他路,比如“登录→搜索→查看详情→退出”。这些场景往往被忽略,但流量不小。
  • 异常路径场景:用户输入错误、网络超时、服务降级时的表现。我曾在项目中遇到过,压测时只测主路径,上线后用户一输错密码,系统直接崩溃——因为没给异常留资源。

建模时,我建议用业务流程图先画一遍,再转成脚本逻辑。别跳步骤,画图能帮你发现很多隐藏的依赖关系。

业务场景建模流程 用户行为分析 主路径场景 分支路径场景 异常路径场景 流量比例分配(如 7:2:1) 脚本逻辑映射 生成可执行脚本 流量比例需根据生产日志调整

3.2 参数化与数据驱动:别让所有用户用同一个账号

这是新手最容易犯的错。录完脚本,跑压测,1000个并发用户全用同一个账号登录。结果呢?服务端以为是攻击,直接封IP。或者数据库里一条记录被1000个线程同时更新,死锁了。

参数化,就是让每个虚拟用户用不同的数据。我常用的方式有几种:

参数化方式 适用场景 注意事项
CSV 数据文件 用户账号、商品ID等固定数据集 注意文件编码和行数,别跑着跑着没数据了
函数生成 时间戳、随机字符串、UUID 确保唯一性,别生成重复数据
数据库查询 从生产环境脱敏数据中提取 注意查询性能,别把压测变成数据库压测
计数器 需要递增序列的场景 多线程下注意线程安全

数据驱动更进一步——把测试数据和脚本逻辑彻底分离。脚本里只写流程,数据从外部文件读。这样换一套数据就能测不同的业务场景。我曾经用这个方式,一套脚本跑了20多个不同的业务分支,省了不少事。

小技巧:参数化数据量至少是并发数的3倍以上。比如1000并发,准备3000条以上数据。避免数据被循环用完,导致重复。

3.3 关联与断言:让脚本学会“认人”

关联,说白了就是从一个请求的响应里,把动态值取出来,传给下一个请求。比如登录后返回的session ID、下单后生成的订单号。

我见过最惨的案例:脚本里写死了session ID,压测时所有用户共用一个会话。结果服务端以为是同一个用户在疯狂操作,直接限流。压测报告出来,TPS只有200,实际上服务能扛2000。

关联的常见手段:

  • 正则表达式提取:最通用,但写起来麻烦。注意贪婪匹配和换行符。
  • JSON/XML 路径提取:响应是结构化数据时首选,清晰且稳定。
  • 边界值提取:用左右边界字符串定位,适合非结构化响应。

断言呢?就是检查响应对不对。别只检查HTTP状态码200就完事。200不代表业务成功——可能返回的是“系统繁忙,请稍后重试”。

// 一个典型的断言设计(伪代码)
// 1. 检查HTTP状态码 == 200
// 2. 检查响应体包含 "success": true
// 3. 检查响应时间 < 3000ms
// 4. 检查返回的订单号不为空
// 5. 检查数据库状态(可选,用于关键业务)
注意:断言别写太多,否则压测机CPU都花在检查上了。我一般控制在3-5个关键断言,覆盖状态码、业务成功标志、关键字段非空即可。

3.4 事务控制与思考时间:模拟真实用户节奏

事务,就是一组有业务意义的请求集合。比如“下单”这个事务,可能包含“提交订单→支付→查询订单状态”三个请求。事务的响应时间,是这三个请求的总耗时。

我个人习惯把事务定义得粒度适中。太细了,比如把“点击按钮”也算一个事务,没意义。太粗了,比如把“从登录到退出”算一个事务,出了问题你都不知道是哪一步慢的。

事务粒度 示例 分析价值
原子事务 单个API请求 定位具体接口性能问题
业务事务 下单流程(3-5个请求) 评估端到端用户体验
用户会话 从登录到退出(10+请求) 评估整体用户生命周期

思考时间,就是用户操作之间的停顿。用户不会像机器一样连续点击——他会看商品详情、犹豫一下、输入地址。思考时间设得太短,压测结果过于乐观;设得太长,又测不出系统真实瓶颈。

我常用的思考时间模型:

  • 固定思考时间:简单,但不真实。适合基准测试。
  • 随机思考时间:在[min, max]范围内随机取值。更接近真实。
  • 基于日志的思考时间:从生产日志中提取用户操作间隔的分布,然后按分布模拟。这是最真实的,但实现成本高。
避坑指南:我曾经在压测一个电商系统时,把思考时间设成了0。结果TPS冲到5000,服务扛住了,但数据库连接池被打满,导致真实用户登录都进不来。后来加了2-3秒的随机思考时间,TPS降到2000,但系统稳定多了。记住:压测的目标不是跑出最高TPS,而是模拟真实场景下的系统表现。

嗯,脚本设计这块,说到底就是“模拟真实”四个字。参数化让数据真实,关联让流程真实,思考时间让节奏真实。把这些做好了,压测结果才有参考价值。