脚本参数化的主要概念和价值
1. 定义
脚本参数化是指将脚本中固定不变的硬编码值(如用户名、密码、搜索重要词等)替换为变量的过程。这些变量在脚本运行时,从一个预先准备好的数据源中按既定规则读取数据。
2. 主要目的
模拟真实用户行为:在真实场景中,每个用户使用的数据都是不同的。参数化避免了所有虚拟用户使用同一账号、查询同一数据的“不真实”场景,使测试结果更具参考价值。
避免缓存带来的性能失真:如果所有用户都请求相同的数据,服务器和数据库的缓存机制会使得响应时间异常地快,这掩盖了真实环境下处理多样数据的性能瓶颈。参数化通过使用不同数据,迫使服务器执行真正的计算和查询。
支持业务逻辑验证:例如,测试一个用户不能重复登录、一个订单不能被重复支付等业务规则,必须使用不同的参数数据。
实现数据驱动测试:将测试数据和测试逻辑分离,通过更换数据文件即可实现不同业务场景的测试,提升脚本的可维护和复用性。
参数化的详细操作流程
在LoadRunner的Virtual User Generator (VuGen)中进行参数化的标准流程如下:
识别需要参数化的值:在脚本中选中需要替换的常量值(如web_submit_data("login", "Name=username", "Value=testuser", ...)中的"testuser")。
创建参数:右键点击该值,选择 “Replace with a Parameter” 或使用快捷键。
设置参数属性:
参数名称:为其起一个有意义的名字(如 UserName)。
参数类型:选择数据来源的类型(这是主要,下一部分详述)。
属性配置:根据所选类型,配置数据文件路径、列分隔符、数据分配和更新方式等。
参数类型的专业详解
LoadRunner提供了多种参数类型,为了适应不同的测试场景。以下是其中最常用和重要的类型:
1. File(文件类型)
这是最强大、最常用的参数类型,允许你使用外部数据文件(如.dat, .csv, .txt)作为参数源。
配置详解:
文件路径:指定数据文件的位置。建议使用相对路径,以方便脚本迁移。
列分隔符:定义文件中各列的分隔符,默认为逗号(,)。
列配置:为每一列指定一个参数名。例如,文件第一列是用户名,第二列是密码,则可以创建 Param1 和 Param2,并分别重命名为 UserName 和 Password。
“Add Column” / “Delete Column”:管理数据列。
示例数据文件 userdata.dat:
text
user1,password123
user2,password456
user3,password789
...
2. Table(表类型) - 现已整合至File类型
早期版本中独立的数据表类型,现在其功能已完全由 File 类型涵盖。就是使用一个表格化的视图来管理和编辑文件数据。
3. Unique Number(唯一数字)
功能:生成一个在所有Vuser中唯一的数字序列。
重要配置:
Start:序列的起始值。
Block size per Vuser:为每个Vuser预留的数字块大小。例如,起始值为1,块大小为100,则Vuser 1使用1-100,Vuser 2使用101-200,以此类推。这可以有效避免并发冲突。
应用场景:需要唯一标识符的场景,如创建唯一的用户ID、订单号、电子邮件地址等。
4. Random Number(随机数字)
功能:在指定的范围内随机选取一个数字。
重要配置:
Range - From ... to ...:设置随机数的范围。
应用场景:随机查询一个ID范围内的商品、随机选择页码等。
5. User Defined Function(用户定义函数)
功能:允许调用外部DLL文件中的自定义函数来生成参数值。这是最高级、最灵活的参数类型。
应用场景:需要复杂逻辑生成数据的场景,如生成特定格式的加密字符串、调用公司内部的唯一ID生成服务等。
数据分配和更新方式的高级方式
这部分配置决定了Vuser在场景执行过程中如何获取参数数据,是参数化方式的精髓。
A. 选择分配方法 (Select next row)
Sequential(顺序):
描述:按照数据文件的记录顺序,一条一条地读取。当所有数据用完后,根据“When out of values”的设置进行处理。
场景:适用于需要模拟用户按固定流程操作的场景。
Random(随机):
描述:每次迭代时,从数据文件中随机选取一条记录。
场景:模拟用户无规律的操作,常用于浏览、搜索等行为。
Unique(唯一):
描述:为每个Vuser分配一个唯一的、不重复的数据块。这是最重要且最常用于并发测试的模式。
重要配置:需要和“When out of values”方式配合使用。
场景:模拟多个不同用户登录、注册等,保证数据不会重复使用导致业务逻辑错误(如一个账号同时登录)。
B. 更新值的时间 (Update value on)
Each iteration(每次迭代):
描述:每次脚本迭代时,更新参数值。
场景:最常用的方式。例如,用户每次登录都使用不同的账号。
Each occurrence(每次出现):
描述:参数在脚本中每次出现时都更新一次值。这在一个迭代中多次使用同一参数文件的不同值时非常有用。
场景:一个迭代中需要执行多个搜索,且每次搜索的重要词都要求不同。
Once(一次):
描述:在整个Vuser的生命周期中,该参数的值只获取一次,之后保持不变。
场景:模拟用户登录后,在整个会话期间使用同一个Session ID或User ID。
高级技巧
“When out of values” 方式 (针对Unique方式)
Abort Vuser(中止Vuser):数据用完时,强制停止该Vuser。适用于需要精确控制并发用户数和数据量的场景。
Continue in a cyclic manner(循环继续):数据用完后,从头开始循环取数。慎用! 这可能导致数据重复使用,违反“唯一性”的初衷。
Continue with last value(继续使用最后一个值):数据用完后,一直使用最后一条数据。
参数和关联的结合使用
如果一个参数的值依赖于前一个请求的响应(例如,从创建用户的响应中获取用户ID,并在后续查询中使用),你需要先使用关联函数(如 web_reg_save_param_ex)捕获该动态值,然后将其赋值给一个参数,后续步骤即可使用这个参数。
数据文件管理
保证数据文件中的数据量足够多,至少要大于 Vuser数量 * 每个Vuser的迭代次数,特别是在使用Unique方式时。
对于文件类型参数,在Controller中运行时,默认会将数据文件全部加载到每个负载生成器的内存中,以获得最佳性能。请保证负载生成器有足够的内存。
通过精通这些参数化技术和方式,你可以构建出高度模拟真实世界用户行为、能够精准发现系统瓶颈的复杂性能测试场景。