



参数化是LoadRunner的核心功能之一,几乎各种类型虚拟用户都支持参数化功能。参数化实际就是将脚本中的一部分内容做成可以动态取值的参数,使Controller中运行的每个Vuser都可以动态地获取属于自己的数据,更真实地模拟实际用户。如果不使用参数化功能,在Controller中创建的并发Vuser将会进行完全一样的操作,这显然不符合实际情况。因此,LoadRunner引入了参数化功能。通过对脚本中一些数据进行参数化,LoadRunner实现了虚拟用户行为的差异化。
本节将深入讲解参数化的相关知识。
参数化的对象通常是一些和用户业务相关的输入数据,例如录制脚本过程通过键盘输入的数据。如果从脚本开发角度来看,则参数化的对象通常是脚本中函数的参数。对这些数据进行参数化后,每个 Vuser 运行时将会按照参数设置来获取参数,从而进行不同的业务操作。
提示:并不是所有的函数参数都可以进行参数化,例如一些脚本中的常量或者特殊的标识符等。
下面先了解一下参数的创建过程以及主要的参数种类。
启动VuGen,以百度网站作为录制对象,按照下面的流程来录制脚本。
(1)在脚本vuser_init部分,录制打开百度首页的过程。
(2)在Action部分,录制以“LoadRunner”作为关键字的搜索过程。
(3)停止录制生成脚本。
切换到脚本的Aciton部分,可以在脚本中看到关键字“LoadRunner”。选中“LoadRunner”后在其上面单击右键,找到右键菜单“Replace with a parameter”,如图1-31所示。
图1-31 参数化脚本示意
在图1-31中单击“Replace with a parameter”选项,将会打开“选择或创建参数”对话框,如图1-32所示。用户既可以选择一个已经存在的参数来替换字符串“LoadRunner”,也可以创建一个新的参数来替换字符串“LoadRunner”。
在图1-32中,Parameter name用来设置参数的名字,通常定义为有意义的名字,便于以后检查和修改,这里定义为“Keyword”。“Original value”用来设置参数的初始值,这里初始值是“LoadRunner”。“Parameter type”用来设置参数类型,单击列表可以看到全部参数类型,如图1-33所示。
图1-32 参数创建窗口
图1-33 参数类型列表
下面介绍各个参数类型的含义。
(1)DateTime:在需要输入日期/时间的地方,可以用 DateTime 类型参数来替代。其属性设置也很简单,选择一种格式即可,也可以定制格式。
(2)File:文件类型参数,每个Vuser的参数数据根据属性设置从外部文件中来获取。后面会进行深入探讨。
(3)Group Name:在实际运行中,LoadRunner使用该虚拟用户所在的Vuser Group 名称来代替参数。但是在VuGen中运行时,Group Name将会是None。
(4)Iteration Number:在实际运行中,LoadRunner使用该测试脚本当前循环的次数来生成参数。
(5)Load Generator Name:在实际运行中,LoadRunner 使用该虚拟用户所在LoadGenerator 的主机名来代替参数。
(6)Random Number:随机数,在属性设置中可以设置产生随机数的范围。
(7)Table:表类型参数。用法与File类型参数基本一致,可以参考接下来File类型参数的相关内容。
(8)Unique Number:唯一数。在属性设置中可以设置起始数值以及每个用户分配的数据块的大小。例如:如果起始数值为1,每个用户分配的数据块大小为10,那么第一个用户可以用的10个数据依次为1、2、3、…、9、10;第二个用户可以用的10个数据依次为11、12、13、…、19、20;依次类推。具体的取值方式以及数据不够用时的策略需要进行设定,可以参考接下来File类型参数的相关内容。
(9)Vuser ID:在实际运行中,LoadRunner 使用该虚拟用户的 ID 来代替参数值,该ID是由Controller来控制的。在VuGen中运行脚本时,Vuser ID将会是–1。
(10)User Defined Function:从用户开发的dll 文件提取数据,即调用dll中的函数来获取参数。
在图1-33中选择对应的类型后,单击“OK”按钮将会创建一个参数。接下来的工作是设置参数的属性,下节将以文件类型参数为例来讲解如何设置参数的属性。
提示:如果参数化的原始内容在脚本中多次出现,则对其中一个创建参数后还应进行替换操作:用鼠标选中已经创建的参数,单击右键菜单
后将会弹出查找与替换对话框,按照相应的提示进行操作即可完成参数替换工作。
在诸多参数类型中,使用较多的是File类型的参数。因为其功能非常灵活,可以满足大多数Vuser的参数化需求。
在如图1-33所示的对话框中,选择File类型后单击“Properties”按钮,打开参数Keyword的属性配置对话框,如图1-34所示。
提示:用户也可以在图1-33中选择File类型后,单击OK先创建参数,然后再配置参数Keyword的属性。
图1-34 参数属性初始对话框
在图1-34中,单击“Create Table”将创建一个参数文件,默认名称为“Keyword.dat”,参数文件保存在脚本当前路径下。创建完成后,可以看到参数Keyword各个属性均可以设置,如图1-35所示。
如果参数文件已经存在,则可以通过“Browse”(浏览)按钮来进行选择。选择前应该将参数文件复制到脚本当前目录下,以避免在远程Generator上运行脚本时找不到参数文件。
提示:因为参数文件是文本格式的数据,因此通常会把参数文件的扩展名称修改为“.txt”,这样更容易打开进行编辑。实际项目中,经常会通过程序预先创建“.txt”类型的参数文件,然后通过“Browse”(浏览)按钮来进行选择。
图1-35 创建参数文件后的属性设置界面
下面介绍图1-35中各个操作按钮以及配置项的作用。
Add Column:添加一列数据。通常情况下,如果一个脚本中有多个参数,都会放到一个参数文件中,每列对应一个参数。
Add Row:添加一行参数。
Delete Column:删除当前选中的列。
Delete Row:删除当前选中的行。
Edit with Notepad:用记事本程序对当前参数文件进行编辑。
Data Wizard:数据导入向导,用于将外部数据导入到当前参数文件中来作为参数数据。数据既可以来源于外部数据库,也可以来源于Excel等文件。对于数据库,需要注意导出的数据与数据库中的数据不是同步更新的,当数据库中数据有变化时,需要再次进行导出。
“Select column”是当前参数选择列的方式,有“By number”(根据列编号选择)与“By name”(根据列名称选择)两种方式。当一个脚本中存在多个参数且多个参数都在同一个文件中时,需要指定当前参数对应列的数据。
“File format”是文件格式设置,需要配置两个参数。
Column delimiter:当多个参数位于同一个参数文件中时,如何设置各列数据间的分隔标识。分隔标识可以选择Comma(逗号)、Tab(制表符)、Space(空格)中的一种。
First Data line:参数第一行所在的位置。参数通常从第一行来进行取值,不过有时通过参数获取的数据仅能使用一次。而调试程序的时候往往会使用一些数据,这时就可以指定参数从后面没有使用过的一行开始,以保证程序的正确运行。
“Select next row”定义了如何从参数文件中选取下一行数据,有以下几种方式。
Sequential:按照顺序一行行地读取,即同一个脚本的所有虚拟用户使用该参数时,都会从指定的第一行开始进行取值。如果表中没有足够的值,则返回到表的第一行,一直循环到测试结束。这种方式强调虚拟用户的一致性,同一个脚本的各个Vuser取值步调与内容是完全一致的。
Random:每次Vuser访问参数对应数据表时都会随机分配一个参数数据。
Unique:唯一值方式,为每个Vuser的参数分配一个唯一的值。与Sequential相比,Unique强调Vuser取值的差异性,即每个Vuser取到的参数值都不一样。
Same Line As xxxx:如果在一个脚本中定义了多个参数,并且某些参数存在互相对应的关系,这时就可以使用这个选项。例如,如果脚本中存在用户名“username”与密码“password”两个参数,则可以将用户名与密码的参数数据放在同一个参数文件中,然后把密码“password”参数的“Select next row”属性设置为“Same Line As username”,这样每次获取密码“password”的参数值时,就会自动获取与当前“username”参数同一行的“password”参数对应的数据。选择此项后,无需进行“Update value on”的设置。
“Update value on”定义了更新参数值的方式,设置何时再次访问参数文件来更新参数的取值,有3种更新方式。
Each iteration:每次迭代时去访问参数文件的数据表以获得下一个值。如果参数在同一次迭代过程中多次出现,且不发生变化,则可以选择“Each iteration”选项。例如每次迭代时都会申请并处理某一个任务,已经参数化的任务号在同一次迭代中多次出现,则可以使用“Each iteration”方式,以保证每次迭代处理的都是同一个任务。
Each occurrence:参数每次出现时都要更新参数取值。即遇到这个参数就会去访问参数文件的数据表以获得下一个值。因此更新方式设置为“Each occurrence”后,即使参数在同一次迭代中出现多次,每次出现也会重新获取不同的参数值。
nce:同一个参数在脚本执行过程中均取同一个值。例如对于用户名信息,登录后即使多次使用,也不应该发生变化。为了满足类似用户名的参数要求,可以将参数的更新方式设置为“Once”。
“When out of values”用来设置当参数不够用时如何进行处理,共有3种方式.
Abort the Vuser:忽略用户,如果参数不够则当前Vuser进入到Failed状态;
Continue in a cyclic manner:从指定的第一行所在位置开始循环取值;
Continue with last value:用最后获取的参数值继续执行脚本。
“Allocate Vuser values in the Controller”用来设置在Controller中Vuser如何分配参数,有两种设置方式。
Automatically allocate block size:自动分配块的大小,这种方式将会从第一个创建的Vuser开始依次分配参数,如果Vuser不能获取足够的参数,将会按照“When out of values”的策略来执行。
Allocate x values for each Vuser:每个Vuser分配指定x数量的参数,如果Vuser参数不够用将会按照“When out of values”设置的策略来执行。
参数分配方式通常采用默认的“Automatically allocate block size”来自动分配。
提示:在实际项目中,准备足够的参数数据供场景中的 Vuser 使用是一个非常好的习惯,这样可以避免运行场景时去调试一些不必要的运行错误。
下面结合实例来讲解一下在Controller中运行场景时,各个Vuser是如何获取参数的。在图1-35中,单击“Edit with Notepad”,用文本编辑器打开参数文件,第一行是参数名字,第二行是初始值。按照图1-36所示的内容输入参数值。
图1-36 参数文件数据列表
完成后保存并关闭参数文件。在图1-37中可以看到,新添加的参数已经显示在预览区中。在参数数据显示区中,默认最多只能看到100行。如果数据超过100行,可以单击“Edit with Notepad”按钮,进入记事本来查看。
图1-37 修改参数数据后的属性对话框
在图1-37中,单击Close按钮返回到脚本编辑页面。在脚本中可以看到刚刚创建的参数Keyword,如例1-72所示。
例1-72
很多测试工程师尽管能够使用File类型参数,但往往不知道在Controller中各个Vuser的具体取值过程。但是当一些 Vuser 运行过程发生问题时,需要详细跟踪其执行过程,尤其是掌握脚本执行过程中参数的取值情况,以便更好地定位问题的原因。因此,深入了解参数的取值过程是十分必要的。
对于File类型参数,需要掌握“Select next row”与“Update value on”的9种组合取值过程。下面将结合实例来讲解File类型参数如何取值。为了更清晰地了解参数取值规律,可以先将图1-36中的数据放到表1-8中并进行编号,以便更好地体现Vuser与参数所在行的对应关系。
表1-8
续表
表1-9列出了“Select next row”设为Sequential的3种更新方式。可以看出Sequential即顺序取值方式的特点:对于执行同一脚本的Vuser,在执行过程中所有Vuser取值过程与内容是完全一样的,即Vuser取值过程具有一致性的特点。
表1-9
表1-10列出了“Select next row”设为Unique的3种更新方式。可以看出Unique取值方式的特点:对于执行同一个脚本的Vuser,在执行过程中各个Vuser取值过程完全不同,每个Vuser都会从不同的行中进行取值,即Vuser取值过程具有“唯一性”特点。
表1-10
提示:Controller创建的第一个线程就是第一个Vuser,各个Vuser从小到大进行编号,但是不一定从1开始顺序编号。从最小编号的Vuser开始,依次称为第一、第二、……、第N个Vuser。
表1-11列出了“Select next row”设为Random的3种更新方式。可以看出Random取值方式的特点:各个Vuser分别随机进行取值,即取值具有随机性的特点。
了解了File类型参数的使用后,还应该掌握实际项目中创建参数文件的过程:首先分析测试过程中所需的参数个数;其次用文本文件创建参数数据,注意参数的数量应该大于或等于实际需要的参数数量,以减少不必要的麻烦。对于数据来源,既可以自己编写程序创建,也可以编写程序从数据库中导出,更可以直接通过数据向导Data Wizard直接导入数据。
表1-11
如果同一脚本需要创建多个参数,则应尽量把参数都放到一个参数文件中:这样即可以通过“Same Line As xxxx”来设置一些互相关联的参数,又可以更方便地维护参数文件数据。
在实际的脚本开发工作中,通常借助消息函数掌握每个Vuser参数的具体取值。例如,当需要跟踪一些业务处理的细节时,就会通过lr_error_message函数把参数取值信息直接输出到Controller的控制台上。接下来将结合具体例子来讲解这一方法。
示例程序如例1-73所示,它是经例1-72修改后得到的程序,主要用来获取并输出用户的场景执行信息以及参数取值情况。在例1-73的程序中:首先用lr_whoami函数获取用户id、组名称和场景编号,然后调用web_url函数在百度上进行搜索,最后用lr_error_message函数输出用户编号、获取参数和迭代次数信息。
脚本中之所以两次调用 lr_error_message 函数,主要是为了演示更新方式设为“Each Occurrence”的执行效果。因为这种更新方式每次遇到就会重新获取参数,使参数在lr_error_message函数中出现两次可以更好地看到参数取值地变化。对于例1-73的脚本,注意Keyword参数实际上出现了5次。在Controller中运行场景前应该保证参数文件中有足够的参数以供使用。
提示:统计参数出现次数时,应该统计所有的出现次数。例如在例1-73中,虽然语句“lr_eval_string("{Keyword}")”是为了获取参数值,但也应该看做一次出现。
例1-73
Action()
{
int id, scid;
char *vuser_group;
lr_whoami(&id, &vuser_group, &scid);
lr_start_transaction("Search");
web_url("s",
"URL=http://www.baidu.cn/s?wd={Keyword}",
"Resource=0",
"RecContentType=text/html",
"Referer=http://www.baidu.cn/",
"Snapshot=t2.inf",
"Mode=HTML",
EXTRARES,
"Url=http://s.baidu.com/w.gif?path=http://www.baidu.cn/s?wd={Keyword}&t=1220948145240",
"Referer=http://www.baidu.cn/s?wd={Keyword}",ENDITEM, LAST);
lr_end_transaction("Search",LR_AUTO);
lr_error_message("User %d get param %s during iteration %s", id,lr_eval_string("{Keyword}"),lr_eval_string("{iterationID}"));
lr_error_message("User %d get param %s during iteration %s", id,lr_eval_string("{Keyword}"),lr_eval_string("{iterationID}"));
return 0;
}
在例1-73的脚本中,iterationID也是参数,参数类型为“Iteration Number”类型。创建方法比较简单:可以先在lr_eval_string函数的参数中输入任意字符串。例如,整个语句可以先写成下面的形式:
lr_error_message("User %d get param %s during iteration %s", id,lr_eval_string("{Keyword}"),lr_eval_string("abcde"));
然后选中“abcde”并单击鼠标右键,单击“Replace with a parameter”,在弹出的参数设置对话框中,输入参数名称为“iterationID”,然后选择参数类型为“Iteration Number”,最后单击“OK”按钮即完成参数的创建。用户也可以继续单击“Properties”来设置参数的属性,如图1-38所示。
图1-38 参数iterationID的属性
参数创建完成后对应的脚本如下:
lr_error_message("User %d get param %s during iteration %s", id,lr_eval_string("{Keyword}"),lr_eval_string("{iterationID}"));
提示:例1-73的脚本中的用户ID可以不用lr_whoami函数来获取,而是通过创建一个Vuser ID类型的参数来获取。创建以及使用方式可以参考上面iterationID的创建及使用方式。
脚本编译通过后就可以放到Controller中来运行。图1-39为在脚本中将参数Keyword的“Select next row”方式设为“Sequential”、更新方式设为“Each Occurrence”后,然后在场景中设置3个Vuser、迭代2次时的控制台输出信息。
图1-39 控制台输出的参数取值信息
读者可以借助例1-73的脚本,自己来演示File类型其他组合取值方式的运行情况,以更深入地掌握参数化在实际中的应用。