LRlr 关联函数数,系统返回的值如下: 1 5...

LoadRunner&关联函数
web_reg_save_param
注册一个请求,以在检索到的网页中检索并保持一个文本字符串。只要在执行了下一个操作函数(web_url)后才会执行此函数。
将动态数据保存到指定参数。
int web_reg_save_param
(const char *ParamName,
&List of Attributes&, LAST);
//注册函数,保存动态信息
web_reg_save_param
("user_access_number",//参数名称
&&&&"NOTFOUND=ERROR",//未找到时标记错误
&&&&"LB=first-time-visitors.html/",//左边界
&&&&"RB=&Buy
books for a penny" ,//右边界
&&&&"ORD=6",
//匹配的实例数,默认是1,如果设置为All,将所有匹配的参数值保存为数组。
web_url("FirstTimeVisitors",
&&&&"URL=/exec/obidos/subst/help/
&&&&first-time-visitors.html/002-4428&
&&&&"TargetFrame=",
&&&&"RecContentType=text/html",
&&&&"SupportFrames=0",
举例说明:
脚本的背景如下:
  web_submit_data("classiLoanMaterial.jsf_2")(web_submit_data函数的部分省略,下同。)返回的页面上可能存在多条记录,可能一条,可能两条,也可能三条,等等。我们需要将这些记录逐个选中进行操作。注意:不是全部选中,而是要逐条记录进行操作。同时,每一条记录各有一个编号,这是需要进行关联的值。在下面的操作中web_url("directAdjust.jsf","URL=http://128.64.96.105:1158/clpmapp/bizprocess/loanservice/creditassetsriskclassi/classiadjuststepbystep/directAdjust.jsf?approveFormNum=123456")需要使用到该编号,即黑体字部分的值。面对这样的目的,很自然地,我们会想到用一个循环语句来实现。首先,在classiLoanMaterial.jsf页面之前加一个关联如下:
web_reg_save_param("sor","LB=sor\" value=\"","RB=\"","Ord=ALL",
LAST);将Ord参数值设定为ALL,则关联函数将自动把符合条件的关联值保存到参数数组里。在本例中,假设关联值返回三条记录,则LR分别将值保存到sor_1,sor_2,sor_3中,同时,LR还将自动创建一个sor_count变量来保存总的记录数,在这里sor_count值等于3。利用这些信息,我们就可以很方便地在循环语句中实现我们的目的了。步骤如下:
  1、声明各变量:
char sor[50];
char sorvalue[50];
  2、将返回的记录数保存到count变量里:
count=atoi(lr_eval_string("{sor_count}"));
  3、使用for循环:
for(i=1;i&=i++)
&& sprintf(sor,"{sor_%d}",i);
//分别将各个sor值保存到sor字符串中
sprintf(sorvalue,"%s",lr_eval_string(sor));//通过lr_eval_string函数将字符串赋给sorvalue变量
  4、在循环体中使用关联值替换相关值:
  web_url("directAdjust.jsf",
"URL=http://128.64.96.105:1158/clpmapp/bizprocess/loanservice/creditassetsriskclassi/classiadjuststepbystep/directAdjust.jsf?approveFormNum={sorvalue}")
  一切看起来似乎顺理成章,然而如果按照以上的步骤做下来,将会很遗憾地发现:我们定义的{sorvalue}值根本就不被LR认可并接受,于是它将无情地给我们抛出一个错误,说该值是非法的。怎么办?难道我们前面做的一切都白费了吗?
  有句老话说得好:天无绝人之路。聪明而又善良的LR开发团队已经为我们考虑到了这个问题,给我们预备了一个很有用的函数:lr_save_string,它可以帮助我们解决这个问题。于是我们祭出lr_save_string这道最后的杀手锏:
  5、在使用关联值之前进行字符串格式转换:
  lr_save_string(sorvalue,"sorvalue1");
  web_url("directAdjust.jsf","URL=http://128.64.96.105:1158/clpmapp/bizprocess/loanservice/creditassetsriskclassi/classiadjuststepbystep/directAdjust.jsf?approveFormNum={sorvalue1}")
  需要特别注意lr_save_string的用法,它是参数值在前(sorvalue),参数名在后("sorvalue1"),这和一般的习惯用法正好反过来(真是好奇怪!)。而且"sorvalue1"这个参数名称不需要事先声明,它只是一个字符串而已(这也比较奇怪!^_^)。
  到此,我们总算大功告成!脚本回放成功,并且正确达到了预期的效果!打完收工!
  总结:C的变量不能直接在LR的API里调用,所以必须用lr_save_string进行转换。
  最后顺便说一下,lr_save_string这个函数真的很好用,这个例子中提到的方法也适用于另外一些情况,比如说有时候,通过关联函数出来的值我们不能直接使用,还需要做一些特殊的处理时,那么我们可以把关联得到的值取出来,赋给一个字符串,对其进行一番修剪加工后,再用
lr_save_string,就可以使用它来替代需要关联的值了
详细loadRunner关联
:/html/22/n-221222.html
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
要对付这种服务器,我们必须想办法找出这个Session ID到底是什么、位于何处,然后把它撷取下来,放到某个参数中,并且取代掉脚本中有用到Session ID的部份,这样就可以成功骗过服务器,正确地完成整个交易了。二、什么时候需要做关联& && &&&要想弄清这个问题,我们首先要知道客户端与服务器端的请求与响应的过程& && &&&过程说明:& && &&&客户端发出获得登录页面的请求,服务器端得到该请求后,返回登录页面,同时动态生成一个Session Id& && &&&当用户输入用户名密码,请求登录时,该Session Id同时被发送到服务器端;如果该Session Id在当前会话中有效,那么返回登录成功的页面,如果不正确则登录失败。
&&&&&&&&在第一次录制过程中LR把这个值记录了下来,写到了脚本中,但再次回放时,客户端发出同样的请求,而服务器端再一次动态的生成了Session Id,此时客户端浏览器再次输入用户名和密码时,请求登录,还是用旧的Session Id,发出的请求就是错误的,为了获得这个动态的session Id我们这里用到了关联。
&&&&&&&&所以我们得出结论:& && &&&当客户端的某个请求是随着服务器端的相应而动态变化的时候,我们就需要用到关联。(凡是脚本每次执行时都必须获得唯一标识的地方都需要关联。)
&&&&&&&&当然我们在录制脚本时应该对测试的项目进行适当的了解,知道哪些请求需要用到服务器响应的动态值,如果我们不明确那些值需要做关联的话,我们也可以将脚本录制两遍,通过对比脚本的方法来查找需要关联的部分,但并不是说两次录制的所有不同点都需要关联,这个要具体情况具体分析。
&&&&&&& 如何做关联?
&&&&&& 关联会用到下列函数:
&&&&&&&web_reg_save_
&&&&&& web_create_html_
&&&&&& web_create_parmam_
&&&&&&& 其中,web_reg_save_param的语法为:
&&&&&& web_reg_save_param("parameter& Name" , &list of Attributes&, LAST);
&&&&& web_create_html_param和web_create_parmam_ex这两个函数主要是保留以兼容以前旧版本。建议使用web_reg_save_param.
&&&& 那么,如何找出要关联数据呢?简单地说,每一次执行时都会变动的值,就有可能需要做关联。VuGen提供两种方式帮助用户找出需要做关联的值:自动关联和手动关联。
三、关联有两种机制,自动关联和手动关联:&&&&&&&&首先谈谈自动关联
&&&&&&&&VuGen内建自动关联引擎(Auto-correlation Eengine),提供Rules Correlation 和Correlation Studio 两种机制,可以自动找出需要关联的值,并且自动使用关联函数建立关联。
&&&&&&& 1、“Rules Correlation”:在录制过程中VuGen 会根据使用者事先制订的规则,实时自动找出要关联的值。规则的来源有内建(Built-in Correlation)和使用者自定义(User-defined& Rules Correlation)关联规则两种。
&&&&&&&内建(Built-in Correlation):VuGen已经针对常用的一些应用系统,如AribaBuyer、BlueMartini、BroadVision、InterStage、mySAP、NetDynamics、Oracle、PeropleSoft、Siebel、SilverJRunner等,内建了一些关联规则。这些应用系统可能会有一种以上的关联规则。
&&&&&& 可以在单击“VuGen”启动&在菜单【Tool】&【Recording Options】&【HTTP Properties】&【Correlation】中启用关联规则,启动关联后,当录制这些应用系统脚本时,VuGen会在脚本中自动建立关联。也可以在【Recording Options】&【HTTP Properties】&【Correlation】检视每个关联规则的定义。
&&&&&&& 除了内建的关联则之外,使用者也可以自定关联规则。可以在【Recording Options】&【HTTP Properties】&【Correlation】建立新的关联规则。
&&&&&&& 请依照以下步骤使用“Rule Correlation”:
&&&&&&& 单击“VuGen”启动&在菜单【Tool】&【Recording Options】&【HTTP Properties】&【Correlation】,勾选“Enable correction during& recording”,以启动自动关联。如下图所示:
&上面两个图片,都可以启动Recording Options,勾选“Enable correction during& recording”,以启动自动关联。
&&&&&&& 假如录制的应用系统属于内建关联规则的系统,如AribaBuyer、BlueMartini、BroadVision、InterStage、mySAP、NetDynamics、Oracle、PeropleSoft、Siebel、SilverJRunner等,请勾选相应的应用系统。或者可针对录制的应用系统加入新的关联规则,此即为使用者自定的关联规则。
&&&&&& 以下是自动关联的脚本,如下图所示:
&&&&&& 自动关联时VuGen会侦测到复核关联规则的数据,以下为处理方式:
&&&&&& 首先会跳出一个“Correlation warning”:消息对话框窗口,选择“Issue a pop-up message and let medecide online”:询问用户是否建立关联,每遇到一次询问一次,以了解每个关联数据的内容和位置。如果每次询问很麻烦,可以选择“Perform correlation in script”(直接自动建立关联)。
&&&&&&&2、“Correlation Studio”:有别于“Rules Correlation”,“Correlation Studio”是在执行脚本后才会建立关联,也就是说当录制脚本后,脚本至少需被执行过一次时“Correlation Studio”才会起作用。“correlation studio”会尝试找出录制时与执行时,服务器响应内容的差异部分,藉以找出需要关联的数据,并建立关联。
&&&&&& 当录制的应用系统不属于VuGen预设支持的应用系统时,“Rule correlation”可能无法发挥作用,这是可以利用“Correlation Studio”来进行关联。
&&&&&& 使用“Correlation Studio” 的步骤如下:
(1)录制脚本并执行。
(2)执行完毕后,VuGen会跳出“Scan Action for Correlation”窗口,询问用户是否要扫描脚本并建立关联,单击“yes”按钮,扫描脚本。
(3)扫描完后,可以在脚本下方的“Correlation Results”中看到扫描的结果。
(4)检查一下扫描的结果,选择要做关联的数据,然后单击“Correlation”按钮,逐次关联,或是单击“Correlate All” 让VuGen 一次就对所有的数据建立关联。
&&& 注意:由于Correlation& studio会找出所有有变得的数据,但是并不是所有的数据都需要做关联,所以不是建议用户直接“Correlate All”。
重复步骤(1)~(4),直到所有需要做关联的数据都找出来为止。
&&& 注意:有时关联的地方有多处,前面的管理如果没有执行通过,执行将停止验证脚本的正确性,后面需要做关联的部分无法被扫描出来。
四、手动关联
&&&&&&&& 手动关联的步骤如下:
&&&&&&& 第一步:录制测试脚本,录制两遍;
&&&&&&&&&&& 第二步:使用WinDiff工具找出两次脚本的不同,判断是否需要进行关联;
&&&&&&&&&&& 第三步:使用web_reg_save_param函数手动建立关联;
&&&&&&&&&&& 第四步:将脚本中有用到关联的数据,已参数代替;
   具体执行如下:&&&&&&& 第一步:录制测试脚本,录制两遍;先录制一份脚本存档,取名为loginA,再依照相同的操作步骤与数据录制第二份脚本并保存,取名为loginB并关闭loginB;(两次录制的操作步骤及使用数据最好保持一模一样)&&&&&&& 第二步:使用WinDiff工具找出两次脚本的不同,判断是否需要进行关联;在脚本loginA中,单击VuGen的菜单tool→compare with vuser...,并选择loginB,如下图所示:
&&第三步:接着WinDiff会开启,同时显示两份脚本,并显示有差异的地方。WinDiff会以一整行***标示有差异的脚本,并且以红色的字体显示真正差异的文字。(假如没有看到红色字体,请单击“Options&View&Show inline Differences”)如下图所示:
&逐一检查两份脚本中差异的部分,每一处差异都有可能是需要做关联的地方,选取差异的脚本,然后复制。在复制时,有时并不需要整行脚本,可能只会选择脚本中的一部分。注意:lr_thik_time是用来模拟每个步骤之间使用者思考延迟的时间,这一部分可以忽略。接着打开Recording Log(单一协议)或是Generation Log(多重协议)中找到这个值。我个人推荐在Generation Log的第一行开头,按Ctrl+F组合键,开始“find”窗口,黏上刚刚复制的脚本,找出其在Generation Log第一次出现的位置。例如:上图中一行和第二行的差异已经让系统自动做了关联,故不管;在第三行中两个脚本存在差异性。差异的地方在【LT-68750-afrD2frlzMHDQ1wwDsjlNugZgY0mxw】,此时复制这一差异点,在Generation Log中进行查找。查找的结果如下图所示:
&找到数据后,看此差异在什么地方,检查数据的标头,例如上面查找的【LT-68750-afrD2frlzMHDQ1wwDsjlNugZgY0mxw】在Body区域,如下图所示:
&一般情况下关联函数写到发出请求的函数之前就可以了。如下图所示:
&第四步:插入关联函数  在插入关联函数前,我们先介绍关联函数web_reg_save_param  一个web_reg_save_param函数的例子:& && web_reg_save_param ("sessionid","LB=Session_id:","RB=;","Search=Body",LAST);
& & 在这里我们只介绍几个常用参数的含义  语法:int web_reg_save_param(const char *ParamName, &list of Attributes&, LAST);  参数说明:  ParamName: 存放得到的动态内容的参数名称;  list of Attributes: 其它属性,包括:Notfound, LB, RB, RelFrameID, Search, ORD, SaveOffset, Convert, SaveLen。属性值不分大小写;  LB( Left Boundary ) : 返回信息的左边界字串。该属性必须有,并且区分大小写;  RB( Right Boundary ): 返回信息的右边界字串。该属性必须有,并且区分大小写;  Search : 返回信息的查找范围。可以是Headers,Body,Noresource,All(缺省)。该属性质可有可无。  怎么插入关联函数呢?&&&&& 根据我的经验,当找到两个脚本的差异后,在对应区域插入关联函数,单击回车键,显示一行为空,在此行可以手动输入关联函数web_reg_save_param("参数名称","左边界","右边界","查询区域",LAST);或单击鼠标右键单击【insert】&【net step...】&在add step界面,step type中选择services&web_reg_save_param,单击【ok】键,弹出如下图所示:
单击【OK】键,显示如下信息:
web_reg_save_param("lt",&&"LB/IC=name=\"lt\" value=\"",&&"RB/IC=\"",&&"Ord=1",&&"Search=Body",&&LAST);
对脚本中需要参数化进行替代,如下图所示:
对于确定参数的左右边界,我个人建议是在找到脚本中差异性的地方【LT-68750-afrD2frlzMHDQ1wwDsjlNugZgY0mxw】后复制,然后在Generation Log日志中通过ctrl+F组合键查找,如下图所示:
&对于引号需要使用【\】作转义,例如上面的左边界可以写成name\"lt\"& value=\"&& ,右边界可以写成\"& 。
第五步:验证关联函数是否正确。
首先设置一下输出日志,在VuGen的工具栏运行时设置【Run-time Settings】&log&勾选Enable logging&Always send messages&Extended log&勾选Parameter substitution。个人观念,在负载测试时不需要输出参数日志,改为Standard log日志即可,因为输出参数日志也需要时间。如下图所示:
&回放脚本时,会在Replay Log日志中可以显示关联参数的相应值,此值是动态变化的,每一次执行后,显示的值都不一样。如下图所示:
参数说明:
int web_reg_save_param (const char *mpszParamName, &List of Attributes&, LAST);
ParamName:存放动态数据的参数名称。
list of Attributes:其他属性,包含 “Notfound”、“LB”、“RB”、“RelFrameID”、“Search”、“ORD”、“SaveOffset”、“Convert”以及“SaveLen”。
下面将详细说明每个属性值的意义:
1、Notfound:指定当找不到要找的动态数据时该怎么处理。
当指定Notfound=error时,表示着找不到动态数据时,就发出一个错误消息。此为该属性的默认值。
当指定Notfound=warning时,表示当找不到动态数据时,不发出错误消息,只发出警告,脚本也会继续执行下去不会中断。在对脚本出错时,可以如此设置。
2、LB:动态数据的左边界字符串。此属性是必须要有的,而且区分大小写。
3、RB:动态数据的右边界字符串。此属性是必须要有的,而且区分大小写。
4、RelFrameID:相对于URL而言,欲搜寻的网页的Frame。此属性可以是All或是数字,而且可有可无。
5、Search:搜寻的范围,其值可以是Headers(只搜寻headers)、Body(只搜寻body部分,不搜寻header)、Noresource(只搜寻body部分,不搜寻header与resource)或是All(搜寻全部范围,此为默认值),此属性可有可无。
6、ORD:指明从第几次出现的左边界开始才是要撷取的数据,默认值是1。假如该属性值为All,则所有找到符合的数据会存储在数组中。此属性可有可无。
7、SaveOffset:当找到符合的动态数据时,从第几个字符开始才开始存储到参数中。此属性值不可为负数,其默认值为0。
8、Convert:转换数据格式。当指定该属性值为HTML_TO_URL时,意味着将HTML-encoded数据转成URL-encoded数据格式。如果是HTML_TO_TEXT,表示将HTML-encoded数据转成纯文字数据格式。
9、SaveLen:当找到匹配项后,偏移量之后的几个字元存储到参数中。此参数可有可无,默认值是-1,表示一直到结尾的整个字符串都存入参数中。
转义字符总结
在做手动关联时,取边界值的时候,会经常用到转义字符,现将转义字符整理如下:
\t 水平制表
\v 垂直制表
\? 问号字符
\' 单引号字符
\" 双引号字符
&&以上是整个自动关联和手动关联的过程,其中有一些网上总结,同时也有个人观念,若有异议,请吐槽。&
阅读(8969)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'如何做LR自动关联和手动关联?',
blogAbstract:'\r\n一、什么时候需要关联&& & & & 1.关联的含义& && &&&关联的含义A(correlation):在脚本回放过程中,客户端发出请求,通过关联函数所定义的左右边界值(也就是关联规则),在服务器所响应的内容中查找,得到相应的值,已变量的形式替换录制时的静态值,从而向服务器发出正确的请求,这种动态获得服务器响应内容的方法被称作关联。\r\n&&&&&&& 关联的含义B(correlation):就是把脚本中某些写死的代码(hard_coded)数据,转变成撷(xie)取自服务器所送的、动态的、每次都不一样的数据。\r\n&&',
blogTag:'',
blogUrl:'blog/static/2',
isPublished:1,
istop:false,
modifyTime:3,
publishTime:6,
permalink:'blog/static/2',
commentCount:1,
mainCommentCount:1,
recommendCount:4,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}虚拟解释变量回归_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
虚拟解释变量回归
上传于||文档简介
&&虚拟解释变量
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩1页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢

参考资料

 

随机推荐