脚本开发遇到的问题:
1)被业务场景所迫: 所有用户都输入相同的数据,不能体现出真实的业务环境。(搜索操作)
2)被系统体系所迫: 存在缓存,不能体现出真正的性能。
3)被系统业务约束所迫: 有些系统禁止一个用户多次登陆的系统,也就严重到无法测试的地步 了。
Loadrunner中提供一种机制帮助解决上述问题, 叫参数化(parameterization)
参数化
LoadRunner中的参数化和 函数的参数 不要混淆
那些能参数化
大部分情况下只有函数的参数才能参数化,但也不是所有函数的参数都可以参数化。
需要参数化的:
1、登陆认证信息
2、一些和时间相关的,违反时间约束的
3、一些受其他字段约束的
4、一些来自于其他数据源(例如数据库的)
5、其他在运行过程中需要变动的
Action() { int i={NewParam}; //错误的参数化 return 0; } Action.c (3): undeclared identifier `NewParam'
参数化方法
下面演示参数化
Action() { web_url("s", "URL=https://www.baidu.com/s?wd=ccc", "Resource=0", "RecContentType=text/html", "Referer=http://www.baidu.com/", "Snapshot=t6.inf", "Mode=HTTP", LAST); return 0; }
运行结果
下面对,kw进行参数化。右键ccc
这时候参数化后,显示参数化变量。前后大括号在 tool-generaloptions设置。
设置参数内容:右键参数名
可添加列,searchtext.dat文件在保存路径下。
用记事本编辑,记事本最后一定要且只有一个空行。不然lr会报错。
设置action迭代次数为3.可将每次请求的kw换成数据列中的数据。
运行将参数输出到log。
运行结果:
Action.c(3): 通知: 参数替换:参数“searchtext”=“ccc” Action.c(3): 通知: 参数替换:参数“searchtext”=“bbb” Action.c(3): 通知: 参数替换:参数“searchtext”=“aaa”
2、参数化取值方法
select next row : 获取下一行数据的方式
Sequential:顺序
Random:随机
当参数文件为:
text 1 2 3 4 5
前面2种对于虚拟用户来讲,都是按以下顺序执行:
user1:1,2,3,4,5, user2:1,2,3,4,5, user3:1,2,3,4,5, user4:1,2,3,4,5,
Unique:唯一。这个值,我这个user选了这个参数,其他的user都不能选。
参数searchtext的值为
searchtext 1 2 3 4 5
代码
Action() { lr_output_message("当前的参数值是:%s",lr_eval_string("{searchtext}")); return 0; }
1、选择AbortVuser。Action迭代6次返回结果。超出范围,Vuser被终止。
Action.c(3): 通知: 参数替换:参数“searchtext”=“5” Action.c(3): 当前的参数值是:5 正在结束操作 Action。 正在结束迭代 5。 正在开始迭代 6。 错误: 参数 'searchtext': 表 'searchtext.dat' 中没有该参数的其他唯一值[唯一范围是 1-5]。根据“When Out Of Values”策略,Vuser 被中止。
2、选择continue in a cyclic manner。Action迭代6次,运行结果:(在迭代第6次时,从头开始)
正在开始迭代 6。 警告: 参数 'searchtext': 表 'searchtext.dat' 中没有更多唯一值可用于此参数[唯一范围是 1-5]。根据“When Out Of Values”策略,此参数以循环方式继续至范围的起点。 通知: 正在获取参数“searchtext”的新值:表 =“searchtext.dat”列 =“0”行 =“1”。 正在开始操作 Action。 Action.c(3): 通知: 参数替换:参数“searchtext”=“1”
3、选择 continue with last value。Action迭代7次。运行结果(在迭代第6,7次时,用了最后一个value 5):
正在开始迭代 6。 错误: 参数 'searchtext': 表 'searchtext.dat' 中没有该参数的其他唯一值[唯一范围是 1-5]。根据“When Out Of Values”策略,参数从范围的最后一个值继续。 通知: 正在获取参数“searchtext”的新值:表 =“searchtext.dat”列 =“0”行 =“5”。 正在开始操作 Action。 Action.c(3): 通知: 参数替换:参数“searchtext”=“5” Action.c(3): 当前的参数值是:5 正在结束操作 Action。 正在结束迭代 6。 正在开始迭代 7。 错误: 参数 'searchtext': 表 'searchtext.dat' 中没有该参数的其他唯一值[唯一范围是 1-5]。根据“When Out Of Values”策略,参数从范围的最后一个值继续。 通知: 正在获取参数“searchtext”的新值:表 =“searchtext.dat”列 =“0”行 =“5”。 正在开始操作 Action。 Action.c(3): 通知: 参数替换:参数“searchtext”=“5” Action.c(3): 当前的参数值是:5
4、
update value on : 重新获取下一个参数的时机(条件)
Action() { lr_output_message("当前的参数值是:%s",lr_eval_string("{searchtext}")); lr_output_message("当前的参数值是:%s",lr_eval_string("{searchtext}")); return 0; }
选择 Each iteration每次迭代改变 执行结果
Action.c(3): 通知: 参数替换:参数“searchtext”=“ccc” Action.c(3): 当前的参数值是:ccc Action.c(4): 通知: 参数替换:参数“searchtext”=“ccc” Action.c(4): 当前的参数值是:ccc
选择 Each Occurrence 每次遇到一次 就变一次。执行结果
Action.c(3): 通知: 正在获取参数“searchtext”的新值:表 =“searchtext.dat”列 =“0”行 =“1”。 Action.c(3): 通知: 参数替换:参数“searchtext”=“ccc” Action.c(3): 当前的参数值是:ccc Action.c(4): 通知: 参数 searchtext = 2 [表 = searchtext] 的下一行。 Action.c(4): 通知: 正在获取参数“searchtext”的新值:表 =“searchtext.dat”列 =“0”行 =“2”。 Action.c(4): 通知: 参数替换:参数“searchtext”=“bbb”
选择Once 不管action被迭代多少次都不会变。 这里吧action迭代设置为2的结果如下:
正在开始迭代 1。 正在开始操作 Action。 Action.c(3): 通知: 参数替换:参数“searchtext”=“ccc” Action.c(3): 当前的参数值是:ccc Action.c(4): 通知: 参数替换:参数“searchtext”=“ccc” Action.c(4): 当前的参数值是:ccc 正在结束操作 Action。 正在结束迭代 1。 正在开始迭代 2。 正在开始操作 Action。 Action.c(3): 通知: 参数替换:参数“searchtext”=“ccc” Action.c(3): 当前的参数值是:ccc Action.c(4): 通知: 参数替换:参数“searchtext”=“ccc” Action.c(4): 当前的参数值是:ccc 正在结束操作 Action。
总结:
1、根据你需要的参数获取方式设置不同的组合,满足你的需求
2、select next row能随即尽量随机
3、使用不同用户登录一次使用 Unique + Once模式
随机数
也可以点击这里进行参数化设置。
2个参数对应一个文件的不同列
LR自带测试网站 WebTours 注册demo
Action() { web_url("WebTours", "URL=http://127.0.0.1:1080/WebTours/", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t14.inf", "Mode=HTML", LAST); web_link("sign up now", "Text=sign up now", "Snapshot=t15.inf", LAST); web_submit_form("login.pl", "Snapshot=t16.inf", ITEMDATA, "Name=username", "Value={username}", ENDITEM, "Name=password", "Value={password}", ENDITEM, "Name=passwordConfirm", "Value={password}", ENDITEM, "Name=firstName", "Value=f", ENDITEM, "Name=lastName", "Value=l", ENDITEM, "Name=address1", "Value=s", ENDITEM, "Name=address2", "Value=c", ENDITEM, "Name=register.x", "Value=48", ENDITEM, "Name=register.y", "Value=10", ENDITEM, LAST); return 0; }
参数化和变量的区别
1)参数作用域远远大于局部变量,在一个action中的参数可以再另一个函数使用,而局部变量不行,除非是全局 变量。
参数和变量的转换
1)参数转换成变量 lr_eval_string 读取参数的值
2)变量转换成参数 lr_save_string 创建参数。可以将变量写入参数。
Action() { int a =10; char name[]="lr"; lr_output_message("变量的取值是:%d",a); lr_output_message("参数的取值是:%s","{output}"); lr_output_message("参数的取值是:%s",lr_eval_string("{output}")); lr_save_int(a,"p"); //lr_save_string(name,"p"); lr_output_message("参数的取值是:%s",lr_eval_string("{p}")); return 0; } Action.c(5): 变量的取值是:10 Action.c(6): 参数的取值是:{output} Action.c(7): 参数的取值是:1 Action.c(10): 参数的取值是:10
从数据库里提取数据
需要配置ODBC