加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

性能测试-关联

(2015-06-24 10:09:47)
标签:

it

分类: 性能测试

一、为什么需要关联

  所谓的关联(correlation)就是把脚本中某些写死的(hard-coded)数据,转变成是撷取自服务器所送的、动态的、每次都不一样的数据。

  服务器在每个浏览器第一次跟它要数据时,都会在数据中夹带一个唯一的辨识码,接下来就会利用这个辨识码来辨识跟它要数据的是不是同一个浏览器。一般称这个辨识码为Session ID。对于每个新的交易,服务器都会产生新的Session ID给浏览器。这也就是为什么执行脚本会失败的原因,因为VuGen还是用旧的Session ID向服务器要数据,服务器会发现这个Session ID是失效的或是它根本不认识这个Session ID,当然就不会传送正确的网页数据给VuGen了。
  要对付这种情况,我们必须想办法找出这个Session ID到底是什么、位于何处,然后把它撷取下来,放到某个参数中,并且取代掉脚本中有用到Session ID的部份,这样就可以成功骗过服务器,正确地完成整个交易了。

 

二、常用关联函数

  web_reg_save_param(),一般用在提交web_submit_form,或web_url函数之前

1、简要说明
语法:int web_reg_save_param(const char *ParamName, , LAST);

2、参数说明:
ParamName: 存放得到的动态内容的参数名称
list of Attributes: 其它属性,包括:Notfound, LB, RB, RelFrameID, Search, ORD, SaveOffset, Convert, SaveLen。属性值不分大小写
Notfound: 当在返回信息中找不到要找的内容时应该怎么处理
Notfound=error: 当在返回信息中找不到要找的内容时,发出一个错误讯息。这是缺省值。
Notfound=warning: 当在返回信息中找不到要找的内容时,只发出警告,脚本也会继续执行下去不会中断。
LB( Left Boundary ) : 返回信息的左边界字串。该属性必须有,并且区分大小写。如果不想区分大小写,可以在LB后加/IC。
RB( Right Boundary ): 返回信息的右边界字串。该属性必须有,并且区分大小写。如果不想区分大小写,可以在LB后加/IC。
RelFrameID: 相对于URL而言,欲查找的网页的Frame。此属性质可以是All或是数字,该属性可有可无。
Search : 返回信息的查找范围。可以是Headers,Body,Noresource,All(缺省)。该属性质可有可无。
ORD : 说明第几次出现的左边界子串的匹配项才是需要的内容。该属性可有可无,缺省值是1。如为All,则将所有找到的内容储存起来。
SaveOffset : 当找到匹配项后,从第几个字元开始存储到参数中。该属性不能为负数,缺省值为0。
SaveLen :当找到匹配项后,找到的值的子字符串的长度(在指定的偏移量中),将保存到参数。缺省值是-1,表示一直到结尾的整个字串都存入参数。
Convert : 可取的值有以下两种:

  • HTML_TO_URL : 将 HTML-encoded 资料转成 URL-encoded 资料格式
  • HTML_TO_TEXT : 将 HTML-encoded 资料转成纯文字资料格式

3、函数的一些使用技巧:
        1)、web_reg_save_param必须在获取返回值的操作前面注册,在获取返回值的操作后面使用
        2)、保存参数最大不能超过256字节,如果超过256字节请使用int web_set_max_html_param_len (const char *length )函数扩大参数保存范围
        例如:web_set_max_html_param_len ("1024"); //扩大参数最大保存范围为1024字节
        3)、LB和RB后面跟着"/ic",则边界大小写都匹配(不加,也就是默认是大小写敏感的)
        例如:web_reg_save_param("IsRight","LB/ic=cache-control: private\r\n\r\n","RB/ic=|",LAST);

三、实例讲解:
目的:取得页面中的商品状态,如果状态是正常态就改为注销态,否则改为正常态。

录制脚本使用的是URL based s cript
http://www.cydtest.com/wp-content/uploads/2013/03/web_reg_save_param1.jpeg

将返回的数据记录到日志
http://www.cydtest.com/wp-content/uploads/2013/03/web_reg_save_param2.jpeg

直接手工访问页面,检查URL
http://www.cydtest.com/wp-content/uploads/2013/03/web_reg_save_param3.jpeg

该页面上点击右键,选择属性
http://www.cydtest.com/wp-content/uploads/2013/03/web_reg_save_param4.jpeg

看到URL,对照录制下的脚本中有:

CODE:
01
02
03
04
05
06
07
08
09
10
11
web_url("modifyOfferingStatePage.do",
"URL={url}/web/businessAccept/order/modifyOfferingStatePage.do?offeringId=
282172&offeringSpecId=1&offeringSpecName=普通宽带(ADSL/LAN)&customerName=
{clientname}&nodeId=260000&pos1=定购管理&pos2=修改商品状态",
 
"Resource=0",
"RecContentType=text/html",
"Referer={url}/web/businessAccept/order/orderMenu.do",
"Snapshot=t23.inf",
"Mode=HTTP",
LAST);

于是在这段代码前添加注册函数:

CODE:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
web_reg_save_param("oldstate",
"LB/IC=原有商品状态:",
"RB/IC=",
"Search=body",
"Ord=1",
"RelFrameId=1",
"SaveOffset=57",
"SaveLen=4",
LAST);
web_url("modifyOfferingStatePage.do",
"URL={url}/web/businessAccept/order/modifyOfferingStatePage.do?offeringId=
282172&offeringSpecId=1&offeringSpecName=
普通宽带(ADSL/LAN)&customerName={clientname}&nodeId=
260000&pos1=定购管理&pos2=修改商品状态",
 
"Resource=0",
"RecContentType=text/html",
"Referer={url}/web/businessAccept/order/orderMenu.do",
"Snapshot=t23.inf",
"Mode=HTTP",
LAST);
...............
//将得到的内容存入日志用于检查
lr_log_message("getvalue : %s",lr_eval_string ("{oldstate}"));
 
if ( lr_eval_string ("{oldstate}") == "正常"){
web_submit_data("modifyOfferingState.do",
"Action={url}/web/businessAccept/order/modifyOfferingState.do",
"Method=POST",
"RecContentType=text/html",
"Referer={url}/web/businessAccept/order/modifyOfferingStatePage.do?offeringId=
282172&offeringSpecId=1&offeringSpecName=普通宽带(ADSL/LAN)&customerName=
{clientname}&nodeId=260000&pos1=定购管理&pos2=修改商品状态",
 
"Snapshot=t24.inf",
"Mode=HTTP",
ITEMDATA,
"Name=offering.state", "Value=1", ENDITEM,
"Name=offering.recentModifyReason", "Value=修改原因", ENDITEM,
"Name=offering.customerId", "Value=281218", ENDITEM,
"Name=offering.offeringId", "Value=282172", ENDITEM,
"Name=offering.offeringSpecId", "Value=1", ENDITEM,
"Name=offering.recentMender", "Value=root", ENDITEM,
"Name=offering.recentModifyDatetime", "Value=2005-01-16", ENDITEM,
"Name=nodeId", "Value=260000", ENDITEM,
"Name=customerName", "Value={clientname}", ENDITEM,
"Name=offeringSpecName", "Value=普通宽带(ADSL/LAN)", ENDITEM,
"Name=submit.x", "Value=33", ENDITEM,
"Name=submit.y", "Value=13", ENDITEM,
LAST);
}
Else
{
web_submit_data("modifyOfferingState.do",
"Action={url}/web/businessAccept/order/modifyOfferingState.do",
"Method=POST",
"RecContentType=text/html",
"Referer={url}/web/businessAccept/order/modifyOfferingStatePage.do?offeringId=
282172&offeringSpecId=1&offeringSpecName=普通宽带(ADSL/LAN)&customerName=
{clientname}&nodeId=260000&pos1=定购管理&pos2=修改商品状态",
 
"Snapshot=t24.inf",
"Mode=HTTP",
ITEMDATA,
"Name=offering.state", "Value=0", ENDITEM,
"Name=offering.recentModifyReason", "Value=修改原因", ENDITEM,
"Name=offering.customerId", "Value=281218", ENDITEM,
"Name=offering.offeringId", "Value=282172", ENDITEM,
"Name=offering.offeringSpecId", "Value=1", ENDITEM,
"Name=offering.recentMender", "Value=root", ENDITEM,
"Name=offering.recentModifyDatetime", "Value=2005-01-16", ENDITEM,
"Name=nodeId", "Value=260000", ENDITEM,
"Name=customerName", "Value={clientname}", ENDITEM,
"Name=offeringSpecName", "Value=普通宽带(ADSL/LAN)", ENDITEM,
"Name=submit.x", "Value=33", ENDITEM,
"Name=submit.y", "Value=13", ENDITEM,
LAST);
}

从日志中截取的真实的返回内容为:
vuser_init.c(689):
\r\n vuser_init.c(689):\r\n
vuser_init.c(689): 原有商品状态:

\r\n
vuser_init.c(689):
正常

\r\n
vuser_init.c(689):

\r\n
vuser_init.c(689):
\r\n vuser_init.c(689):\r\n
vuser_init.c(689): 修改后的状态:

\r\n
vuser_init.c(689):
\r\n
vuser_init.c(689): \r\n
vuser_init.c(689): \r\n
vuser_init.c(689): \r\n
vuser_init.c(689):
可以看到左边界是:原有商品状态:《/td》,
右边界是:《/td》,偏移量为:57(包括了空格),
长度为:4(因为一个汉字长度为2),最后存入变量的值是:正常

4.经验总结
1)为了便于脚本的调试,将返回的数据都写入日志是个好办法;
2)为了验证取得的数据是否是自己期望的,可以将取得的数据写入日志中进行验证,
例:lr_log_message(“getvalue : %s”,lr_eval_string (“{oldstate}”));
3)因为它是一个注册函数,必须在返回信息前使用,所以注册的位置必须正确,否则很可能得到类似如下错误:
4)vuser_init.c(734): Error -27190: No match found for the requested parameter “oldstate”.
Check whether the requested boundaries exist in the response data. Also,
if the data you want to save exceeds 1024 bytes,
use web_set_max_html_param_len to increase the parameter size [MsgId: MERR-27190]
5)vuser_init.c(734): Error -27187: The above “not found”
error(s) may be explained by header and body byte counts being 0 and 0,
respectively. [MsgId: MERR-27187]
6)vuser_init.c(734):
web_concurrent_end highest severity level was “ERROR” [MsgId: MMSG-27181]
7)所以使用手工方法,右键页面确定在代码中哪个位置之前注册函数至关重要
8)如果脚本中中文为乱码,可能是因为源文件的字符集和操作系统字符集不匹配。试试:
http://www.cydtest.com/wp-content/uploads/2013/03/web_reg_save_param5.jpeg

 

四、关联的二种方式:
自动关联和手动关联

  1. 自动关联

   设置:【Recording Options】>【Http Properties】>【Correlation】中勾选Enable correlation during recording,另外还可以自己建立关联的规则(可不制定),设置完毕。当录制这些应用系统的脚本时,VuGen会在脚本中自动建立关联。

  如果上面这种情况无法关联或无法正确关联,可以尝试另外一种方法:

    1)录制脚本并执行
    2). 执行完毕后,VuGen会跳出下面的【Scan Action for Correlation】窗口,询问您是否要扫描脚本并建立关联,按下【Yes】按钮。

    3). 扫描完后,可以在脚本下方的【Correlation Results】中看到扫描的结果。

    4). 检查一下扫瞄的结果后,选择要做关联的数据,然后按下【Correlate】按钮,一笔一笔做,或是按下【Correlate All】让VuGen一次就对所有的数据建立关联。
    注意:由于Correlation Studio会找出所有有变动的数据,但是并不是所有的数据都需要做关联,所以不建议您直接用【Correlate All】。

  2.  手动关联

 

背景:有可能有些需要做关联的动态数据,自动关联的两种方式都无法侦测出来,这时您就需要自行做手动关联了。

过程
1. 使用相同的业务流程与数据,录制二份脚本
2. 使用WinDiff工具协助找出需要关联的数据
3. 使用web_reg_save_param函数手动建立关联
4. 将脚本中有用到关联的数据,以参数取代
详细步骤

1. 使用相同的业务流程与数据,录制二份脚本
     1). 先录制一份脚本并存档。
     2). 依照相同的操作步骤与数据录制第二份脚本并存盘。注意,所有的步骤和输入的数据一定都要一样,这样才能找出由服务器端产生的动态数据。有时候会遇到真的无法使用相同的输入数据,那您也要记住您使用的输入数据,到时才能判断是您输入的数据,还是变动的数据。
2. 使用WinDiff工具协助找出需要关联的数据
     1). 在第二份脚本中,点选VuGen的【Tools】>【Compare with Vuser…】,并选择第一份脚本。
     2). 接着WinDiff会开启,同时显示二份脚本,并显示有差异的地方。WinDiff会以一整行黄色标示有差异的脚本,并且以红色的字体显示真正差异的文字。(假如没看到红色字体,请点选【Options】>【View】>【Show Inline Differences】)。
     3). 逐一检视二份脚本中差异的部份,每一个差异都可能是需要做关联的地方。选取差异的脚本,然后复制。
在复制时,有时并不需要取整行脚本,可能只会选取脚本中的一部分。
注意:请忽略lr_thik_time的差异部份,因为lr_thik_time是用来模拟每个步骤之间使用者思考延迟的时间。

     4). 接着要在Recording Log(单一protocol)或是Generation Log(多重protocol)中找这个值。将鼠标光标点到Recording Log的第一行开头,按下Ctrl+F,开启【Find】窗口,贴上刚刚复制的脚本,找出在Recording Log第一次出现的位置。

     5). 在Recording Log中找到了要找的数据,这时要确认数据是从服务器端传送过来的。首先可以先检查数据的标头,从标头的Receiving response可以知道数据是从服务器端传送到client端的。假如此数据第一次出现是在Sending request中,则表示此数据是由client端产生,不需要做关联,但是有可能需要做参数化(parameterized)。
您要找的标头格式如下:
*** [tid=b9 Action1 2] Receiving response from host astra.merc-int.com:80 ( 25/11/2002 12:04:00 )

     6). 在找到是由服务器所产生的动态数据之后,接下来要做的就是找出适当的位置,使用web_reg_save_param函数,将这个动态数据撷取到某个参数中。不过在这之前我们要先再重新执行一遍脚本,而且这次会开启所有的Log。

3. 使用web_reg_save_param函数手动建立关联

     执行完脚本之后,在Execution Log中搜寻刚刚复制的字符串。找到字符串后,在字符串前面会有A.tion1.c(7),这个7就是到时候要插入web_reg_save_param函数的位置,也就是要插入到脚本的第7行。在脚本的第7行前插入一行空白行,然后输入 web_reg_save_param(“UserSession”, 
这个 “UserSession” 就是到时要使用的参数名称,建议给个有意义的名字。然后找出左边界和右边界,如:web_reg_save_param(“UserSession”, “LB= input type=hidden name=userSession value=”, “RB=>”, LAST);  

4.将脚本中有用到关联的数据,以参数取代
当使用web_reg_save_param建立参数后,接下来就是用“UserSession”参数去取代脚本中写死的(hard-coded)资料。范例:
将 “Name=userSession”, “Value=75893.0884568651DQADHfApHDHfcDtccpfAttcf”, ENDITEM,
换成 “Name=userSession”, “Value={UserSession}”, ENDITEM,

到这里您已经完成了一个关联了,接下来就是执行脚本,是否能成功运行,假如还是有问题,就要检查看看是否还需要再做另一个关联。

五、关联的常见问题

 1、如何打印出参数值?

      lr_output_message(“Value Captured = %s”, lr_eval_string(“{ParameterName}”));

    具体这两个函数的使用方法,可以参考函数文档

 2、在脚本的data目录下找不到路制时的快照(snapshot)
     造成在脚本的data目录下找不到路制时的快照(snapshot)的可能原因如下:
    o 脚本是由VuGen 6.02或更早的版本所录制的
    o 汇入的Action不会包含快照(snapshot)的档案
    o 脚本是储存在只读的目录下,早成VuGen无法储存执行时撷取的快照(snapshot)
    o 某些步骤并不会产生快照(snapshot),如浏览某个资源
    o 快照(snapshot)功能被取消 。【Tools】>【General options】>【Correlation】tab >【Save correlation information during replay】

 3、开启WinDiff时出现「File no longer available」的错误讯息 
    WinDiff这个工具有些限制,无法开启包含空格符的目录或是脚本,所以建议命名时不要使用空格符,并且尽可能将名称取短一点。

 4、录制时突然跳出【Correlation warning】对话窗口 
    当你有勾选自动关联的【Issue a popup message and let me decide online】选项,当VuGen发现有可能要做关联的数据时,就会跳出【Correlation warning】的窗口,询问你要做关联(Correlation in scrīpt)还是要忽略(Ignore)。
    另外你也可以勾选【Perform correlation in scrīpt】,让VuGen自动作关联,不会再跳出询问窗口。或是勾选【Disable correlation engine】,关闭自动关联的功能。
 5、如何手动启动「Scan action for correlation」的功能

    要手动启动「Scan action for correlation」的功能,请先执行脚本一次后,点选【Vuser】>【Scan Action for Correlation】。 若执行完脚本后并未出现【Scan Action for Correlation】窗口,要启用【Scan Action for Correlation】功能,请点选【Tools】>【General options】>【Correlation】tab,勾选【Show Scan for correlation popup after replay of Vuser】选项。

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有