LoadRunner性能测试系统学习教程:脚本编写之关联函数介绍(7)

上期讲到LoadRunner性能测试脚本编写之关联技术,这期我们一起来学习脚本编写之关联函数介绍。

PART1

关联函数介绍

LoadRunner最新版本中

使用的关联函数为

web_reg_save_param_ex

以前的版本使用的关联函数为

web_reg_save_param

但这两个函数实质差别不大,本文主要介绍关联函数web_reg_save_param_ex

当然在新的版本中关联函数web_reg_save_param还是可用的。

在测试过程中可以通过插入步骤的方式来插入关联函数,在树模式下选中需要插入步骤的位置,单击右键在弹出菜单中选择Insert Before菜单,弹出Add Step对话框,如图所示。
LoadRunner性能测试系统学习教程:脚本编写之关联函数介绍(7)

在Find Function

下拉列表框中输入关联函数

web_reg_save_param_ex

单击OK按钮弹出

web_reg_save_param_ex

对话框,如图所示。

LoadRunner性能测试系统学习教程:脚本编写之关联函数介绍(7)
关联函数web_reg_save_param_ex的格式如下:

intweb_reg_save_param_ex(constcharParamName,[constcharLB, ][constchar*RB,] ,<SEARCH FILTERS>,LAST );

参数说明:

ParamName:表示创建的变量名称。

LB:关联规则的左边界值。

RB:关联规则的右边界值。

List of Attributes:属性列表,具体的内容在后面将详细介绍。

SEARCH FILTERS:指定缓冲区中需要查找的字符串。

LAST:结束参数标志。

1.Parameter Name

变量名,表示将缓存区中查找到的内容保存到这个变量中。

2.Left Boundary

设置查找缓冲区内容的左边界值,当左边界值未设置时或者设置为空值时,那么左边界则从数据的起始位置开始。

例:如待查找的句子"Where and when do you want to travel?",关联函数如下:

web_reg_save_param_ex("When_Txt","LB=Where and ","RB= do", LAST );其中左边界值为“Whereand”右边界值为“do”,查找的结果为“when”。

3.Right Boundary

设置查找缓冲区内容的右边界值,当右边界值未设置时或者设置为空值时,那么右边界则到数据结束处。

例:如待查找的句子"Where and when do you want to travel?",关联函数如下:

web_reg_save_param_ex("When_Txt","LB=Where and ","RB=", LAST );其中左边界值为“Whereand”右边界值为空值,查找的结果为“whendoyou want to travel?”。

在图中可以看到,不管是左边界值还是右边界值,其还有三个设置项:是否区分大小写、是否针对二进制数据进行查找和是否使用正则表达式。而不管对于左边界还右边界来说,这三个选项的设置完成一致,所以进行统一的介绍。

A.Match case(是否匹配大小写)

选中该选项,表示查找过程中,忽略左右界值大小写的问题,即对大小写不敏感。

例:如果需要在以下请求中查找内容。

关联函数代码如下:

web_reg_save_param_ex( "ParamName=test","LB/IC=USERSession value=","RB=>",SEARCH_FILTERS, LAST);

关联后的结果为:

108974.217253949fzAfDzVpDDDzDcpVzHi

其中“LB/IC”表示左边界值不区分大小写,即左边界

“USERSession value=”与“userSession value=”

是一致的,如果区分大小写的话,就无法查找到匹配的值。

B.Binary data(二进制数据查找)

如果需要查找的内容是非ASCII格式,二进制或十六进制格式的内容,这样如果还按常用的左边界和右边界的方式来查找时,就无法找到需要的内容,此时就需要选中Binary data选项,通过二进制的方式来匹配待查找的内容。一般使用“\x”来标识,如\x37。

例:如待检查的二进制内容\xAC\xED\x00\x05\x00。

关联函数如下:

web_reg_save_param_ex( "ParamName=test4","LB/BIN=\xAC\xED\x00","RB/BIN=", SEARCH_FILTERS, LAST);

C.Regular expression(正则表达式匹配)

正则表达式是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在性能测试过程中如果需要匹配的值不是精确的,而是模糊查询,那么此时需要使用正则表达式进行匹配。

LoadRunner中常用的正则表达式匹配的元字符见表所示。

表元字符僦含义

元字符含义

[正则表达式开始的标识

]正则表达式结束的标识

()包括中的内容视为一组内容出现

^匹配以某字符开始,如^abc表示查找以abc开头的字符串

$匹配以某字符结束,如abc$表示查找以abc结束的字符串

.匹配一个字符,该字符可以是任意的字符

?匹配前面一个字符或一组字符,匹配的次数为零次或一次。例如“ab?c”可以匹配“abc”和“ac”,“A(123)?B”可以匹配“AB”和“A123B”

+匹配前面一个字符或一组字符,匹配的次数为一次或多次。例如“ab?c”可以匹配“abbbc”和“ac”,“A(123)?B”可以匹配“AB”和“A123123B”

*匹配前面一个字符或一组字符,匹配的次数为零次或更多次

\转义字符

|匹配“|”前面或后面的字符,例如,“(ABC)|(123)”可以匹配“ABC”或“123”

4.DFEs

DFEs(Data Format Extensions)文件扩展格式。VuGen发生器中支持许多不同类型的数据记录。随着文件格式不断的增加,而VuGen发生器又必须去支持这些格式,有一些格式是专有和使用自定义序列化,但二进制代码和一些无格式的数据很难让人理解,故VuGen发生器增加了数据格式扩展功能(DFEs),这些格式的数据进行转换,这样可以更好的理解这些数据,同时也可以将这些数据做为参数进行关联。

LoadRunner支持的数据扩展格式包括:

Base64 Extension、URL Encodin Extension、JSON Extension和XML Validator Extension四种格式

具体见表。

表数据扩展格式

数据扩展描述

Base64 Extension对Base64编码进行解码(Base64编码是网络传输中最常用的8Bit字节代码的编码方式之一)

URL Encodin Extension对URL编码进行解释(URL编码是一种浏览器用于打包表单输入的格式)

JSON Extension将JSON数据(JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript(Standard ECMA-262 3rd Edition -December 1999)的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等))转换为XML格式

XML Validator Extension接受数据并检查该数据是否符合XML语法,允许VuGen发生器关联xpath查询并且在xml视图中显示出其快照

如以下实例:

iRetVal= web_reg_save_param_ex("ParamName=newParam", "LB/IC=ll", "RB/BIN/RE=RR", "Ordinal=all", "SaveLen=-1", "DFEs=UrlEncoding", SEARCH_FILTERS, "Scope=body",LAST);lr_output_message("Return value = %d (%s).", iRetVal, iRetVal == LR_PASS ? "LR_PASS" : "LR_FAIL" );

注意:如果需要使用DFEs扩展数据功能,那么需要先在Run-time Settings设置对话框中,将【Enable Data Format Extension】复选项设置为可用。

5.Ordinal

Ordinal表示所匹配的内容出现的位置,缺省值为1(指查找待匹配内容,第一次出现的情况),如果将该项值设置为All,是指在缓存中查找所能符合左右边界的内容,并将查找到的结果保存在一个数据中,如果将其设置为1时,那么查找到的结果将保存在一个变量中。

如以下实例,待查找的页面内容如下:

Blue Sky Air 0008am$ 0Blue Sky Air 0011pm$ 0Blue Sky Air 0025pm$ 0Blue Sky Air 00311pm$ 0

关联函数如下:

web_reg_save_param_ex("ParamName=WCSParam_Text1", "LB=outboundFlight value="","RB=;", "Ordinal=All", SEARCH_FILTERS, LAST);

回放的结果如图所示。

LoadRunner性能测试系统学习教程:脚本编写之关联函数介绍(7)
6.Save Offset

Save Offset是指偏量,当使用左右边界值匹配到合适的字符串内容后,可以设置从第几个字符开始截取字符,缺省值为0,即从第一位开始匹配。如匹配到的字符串为“soft testing”,当Save Offset设置为0时,从第一位开始截取,如果设置为2时,那么从第三位开始截取,即返回匹配到的结果为“ft testing”。

例如:HTML中有一段字符串“Astra on the TESTSERVER”,关联函数如下:

web_reg_save_param_ex( "ParamName=WCSParam_Text1","LB=outboundFlight value="", "RB=;", "Ordinal=1", "SaveOffset=2" SEARCH_FILTERS, LAST); 匹配的结果为“ the”。

7.Save Length

Save Length是指设置截取字符串的长度,如果设置为10是指在匹配到的字符中,截取10个字符,缺省值为-1,匹配到字符串结束的位置。通常情况下Save Length属性会与Save Offset属性合起来使用。

例如:HTML中有一段字符串“Astra on the TESTSERVER”,关联函数如下:

web_reg_save_param_ex( "ParamName=WCSParam_Text1","LB=outboundFlight value="", "RB=;", "Ordinal=1", "SaveOffset=0" "SaveLen=2", SEARCH_FILTERS, LAST);匹配的结果为“on”。

8.Frame ID

当页面中有多个帧时,如果需要匹配帧里面的数据时,需要指定某个具体的帧否则无法正确的匹配需要查询的值,通过帧ID号可以指定访问不同的帧,帧的ID最多只能有7位组成,如以下例子,见表。

表帧ID

参数描述

10.0.0.0.0.0.1

1.10.0.0.0.0.1.1

1.20.0.0.0.0.1.2

1.1.10.0.0.0.1.1.1

PART2

关联技术的经典使用

前面详细的阐述了关联函数的参数,从本质上来说,关联函数是一个查找函数,说透了就是从HTML文件内容中查找需要的值,并将其保存在一个变量或数组中。那么换一个角度来看,其实关联函数不单单可以匹配一些变化的值,同样可匹配一些固定的内容,并将其保存到一个数据组,供后续业务使用。也即对关联函数进行扩展使用,在处理业务中这种方式被经常使用到。

实例:以飞机订票系统为例,假设要实现这样的业务,选择好出发城市和到达城市后,在选择航班时,需要选择票价最便宜的航班,如图所示。
LoadRunner性能测试系统学习教程:脚本编写之关联函数介绍(7)

实现思路:首先使用关联函数读取HTML代码中票价和航班号,分别将两部分的数据保存在不同的数组中;接着比较票价,选择找到票价最低的是数组中的最几个元素,即最便宜机票所在数据下;最后将该下标的值对应的读出航班号,就是最便宜的航班。

在使用关联函数进行关联票价与航班号之前,必须首先分析票价和航班号的左边界值和右边界值,关于航班信息的HTML源代码如下:

Blue Sky Air 1008am$ 386Blue Sky Air 1011pm$ 343Blue Sky Air 1025pm$ 365Blue Sky Air 10311pm$ 315

分析上面的源代码可以找到票价与航班号的左边界值和右边界值,关于票价的左右边界值分别为:“center>$”和“”,航班的左右边界值分别为“outboundFlight value=”和“;”。

关联函数的代码如下

(使用web_reg_save_param或web_reg_save_param_ex函数进行关联都可以):

使用web_reg_save_param函数进行关联,票价的关联函数源代码如下:

web_reg_save_param("WCSParam_Text1","LB=center>$ ","RB=</TD>","Ord=All","RelFrameId=1","Search=Body","IgnoreRedirections=Yes",LAST);

航班关联函数源代码如下:

web_reg_save_param("WCSParam_Text2","LB=outboundFlight value=","RB=;","Ord=All","RelFrameId=1","Search=Body","IgnoreRedirections=Yes",LAST);

使用web_reg_save_param_ex函数进行关联,票价的关联函数源代码如下:

web_reg_save_param_ex( "ParamName=fligthcost","LB=center>$ ","RB=</TD>","Ordinal=All", SEARCH_FILTERS, LAST);

航班关联函数源代码如下:

web_reg_save_param_ex( "ParamName=fligthno","LB= outboundFlight value=","RB=;","Ordinal=All",SEARCH_FILTERS, LAST);

注意:在进行关联时Ordinal的属性必须设置为“All”,这样才可以将所有的值匹配到,并将其保存在一个数组中。

确定好左右边界值之后,需要找出所有航班中票价最低的航班,因为一共有4个航班,需要在这4个航班中挑出最便宜的航班,实现思路为设置一个标记,假设票价所保存的数据组最一个元素的值最大(设置标记为flag),那么依次将数组中其它的元素与标记flag进行比较,如果其它元素比flag的值小,就将标记中的值置为当前数组下标所对应的值。实现的代码如下:

//初始化最贵机票,将第一个航班的机票设置为初始化的最贵的机票 max = atoi( lr_eval_string("{WCSParam_Text1_1}") );//初始化标识位,默认设置为1flagno =1;//for循环所有机票for(i =2;i <= atoi(lr_eval_string("{WCSParam_Text1_count}"));i++){sprintf( cost,"{WCSParamText1%d}",i );//比较最前航班的机票是否大于max的值,如果大max的值,即重新对max赋值if(atoi(lr_eval_string(cost)) > max){max = atoi( lr_eval_string(cost) ); flagno = i; } }

找到最容易的机票后,可以得到该数组的下标,那这个数组的下标所对应的航班就是票价最便宜的航班,获取航班号的代码如下:

//通过标识位来确定航班 sprintf( flightelem,"{WCSParamText2%d}",flagno ); lr_save_string( lr_eval_string(flightelem), "flightno");

获得最便宜的票价和航班后,即将这两部分的信息放入到提交的信息中,做为客户端的请求进行提交即可,具体的代码如下:

web_submit_data("reservations.pl_3","Action=http://127.0.0.1:1080/WebTours/reservations.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/WebTours/reservations.pl","Snapshot=t24.inf","Mode=HTTP", ITEMDATA,"Name=outboundFlight","Value={flightno};{flightnocost};10/26/2011", ENDITEM,"Name=numPassengers","Value=1", ENDITEM,"Name=advanceDiscount","Value=0", ENDITEM,"Name=seatType","Value=Coach", ENDITEM,"Name=seatPref","Value=None", ENDITEM,"Name=reserveFlights.x","Value=57", ENDITEM,"Name=reserveFlights.y","Value=13", ENDITEM, LAST);web_submit_data("reservations.pl_4","Action=http://127.0.0.1:1080/WebTours/reservations.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/WebTours/reservations.pl","Snapshot=t25.inf","Mode=HTTP", ITEMDATA, "Name=firstName","Value=test", ENDITEM,"Name=lastName","Value=test", ENDITEM,"Name=address1","Value=", ENDITEM,"Name=address2","Value=", ENDITEM,"Name=pass1","Value=test test", ENDITEM,"Name=creditCard","Value=", ENDITEM,"Name=expDate","Value=", ENDITEM,"Name=oldCCOption","Value=", ENDITEM,"Name=numPassengers","Value=1", ENDITEM,"Name=seatType","Value=Coach", ENDITEM,"Name=seatPref","Value=None", ENDITEM,"Name=outboundFlight","Value={flightno};{flightnocost};10/26/2011", ENDITEM,"Name=advanceDiscount","Value=0", ENDITEM,"Name=returnFlight","Value=", ENDITEM,"Name=JSFormSubmit","Value=off", ENDITEM,"Name=.cgifields","Value=saveCC", ENDITEM,"Name=buyFlights.x","Value=41", ENDITEM,"Name=buyFlights.y","Value=17", ENDITEM, LAST);

该实例是工作中可能常用到的情形,通常会借助关联函数来完善业务流程。

PART3

关联与参数化的区别

参数化和关联方法进行了详细的介绍,但是很多朋友容易将这两者的内容混淆,在本文中详细的介绍两者的区别,主要区别包括以下几点:

1.数据处理的方式不同

参数化的数据是由客户端向服务器提交的,而关联是需要获取服务器返回客户端的数据。在参数化时,参数化的数据会通过web_submit_data提交到服务器,其参数化的策略来自于相关设置选项,关联的数据是从服务器端返回给客户端的,是提交请求的一组验证信息,所以处理关联数据一定是需要从服务器端返回的信息中获取。

  1. 处理的数据是否确定

参数化的数据是测试工程师知道的,也即测试工程师知道需要使用什么数据进行参数化,以满足业务的需要,具体使用什么数据进行参数化,这取决于业务的需要;而需要关联数据的内容是不清楚的,所以只能通过左右边界值来确定。参数化的数据是静态的,即提交的数据可以静态的表示,但关联的数据是动态,即它们之间的原理截然不同。

猜你喜欢

转载自blog.51cto.com/14645850/2540939