2、录制后关联
  当录制前内建关联规则和新建规则都不能满足需要时,或者不知道哪个地方需要关联时,只能采取录制后进行关联。录制后关联与内建关联是有区别的,录制后关联是在执行脚本后才会建立,也是说,当录制完脚本后,脚本至少要执行一次,录制后关联才会产生效果。录制后会尝试找到录制与执行时服务器响应的差异部分,找到需要关联的数据,并建立关联。
  脚本执行后,vuser->scan script for correlations,扫描后,选择需要关联的数据,单击correlate,这时被关联的数据前面会多出一个绿色的勾,即表示关联创建完成了,如图7所示:


  
图7(关联结果)

  关联完成后也是会自动生成web_reg_param关联函数,完整代码示例如下(期间遇到报错error-35061,在代码中有说明解决方法):
Action()
{
web_url("WebTours",
"URL=http://127.0.0.1:1080/WebTours",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTTP",
LAST);
web_url("header.html",
"URL=http://127.0.0.1:1080/WebTours/header.html",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/",
"Snapshot=t2.inf",
"Mode=HTTP",
LAST);
web_url("webtours.png",
"URL=http://127.0.0.1:1080/WebTours/images/webtours.png",
"Resource=1",
"RecContentType=image/png",
"Referer=http://127.0.0.1:1080/WebTours/header.html",
"Snapshot=t4.inf",
LAST);
web_url("hp_logo.png",
"URL=http://127.0.0.1:1080/WebTours/images/hp_logo.png",
"Resource=1",
"RecContentType=image/png",
"Referer=http://127.0.0.1:1080/WebTours/header.html",
"Snapshot=t5.inf",
LAST);
web_url("welcome.pl",
"URL=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/",
"Snapshot=t6.inf",
"Mode=HTTP",
LAST);
web_concurrent_start(NULL);
web_url("home.html",
"URL=http://127.0.0.1:1080/WebTours/home.html",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",
"Snapshot=t7.inf",
"Mode=HTTP",
LAST);
//下面的一行注释和web_reg_save_param_ex关联函数是录制后关联所自动创建的
//Correlation comment - Do not change!Original value='120705.370676387zcAiHicpfAtVzzzHDHcfcpzQfAcf' Name ='CorrelationParameter_1'
web_reg_save_param_ex(//这个关联函数与web_reg_save_param函数实质差别不大
"ParamName=CorrelationParameter_1",//变量名称,表示将缓存区中查找到的内容保存到这个变量中
"LB=userSession value=",//左边界值
"RB=> <table border",//右边界值
SEARCH_FILTERS,//指定缓冲区中需要查找的字符串
"Scope=Body",
//"RequestUrl=*/nav.pl*",     /*因为报错error-35061,所以要注释掉自动生成的关联函数中的这一行*/
LAST);//结束参数标志
web_url("nav.pl",
"URL=http://127.0.0.1:1080/WebTours/nav.pl?in=home",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",
"Snapshot=t8.inf",
"Mode=HTTP",
LAST);
web_concurrent_end(NULL);
web_url("mer_login.gif",
"URL=http://127.0.0.1:1080/WebTours/images/mer_login.gif",
"Resource=1",
"RecContentType=image/gif",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",
"Snapshot=t9.inf",
LAST);
web_concurrent_start(NULL);
web_url("8afc2fe48db9060fe1bdda2089e1d950.png",
"URL=http://act.cmcmcdn.com/upload/201507/8afc2fe48db9060fe1bdda2089e1d950.png",
"Resource=1",
"RecContentType=image/png",
"Referer=http://127.0.0.1:1080/WebTours/",
"Snapshot=t11.inf",
LAST);
web_url("3b491068507d8f85ea7b35d756da7215.png",
"URL=http://act.cmcmcdn.com/upload/201507/3b491068507d8f85ea7b35d756da7215.png",
"Resource=1",
"RecContentType=image/png",
"Referer=http://127.0.0.1:1080/WebTours/",
"Snapshot=t12.inf",
LAST);
web_concurrent_end(NULL);
lr_start_transaction("登录");
lr_think_time(6);
web_submit_data("login.pl",
"Action=http://127.0.0.1:1080/WebTours/login.pl",
"Method=POST",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",
"Snapshot=t15.inf",
"Mode=HTTP",
ITEMDATA,
//用CorrelationParameter_1变量代替常量,即value的值要改为变量值
"Name=userSession", "Value={CorrelationParameter_1}", ENDITEM,
"Name=username", "Value=test1", ENDITEM,
"Name=password", "Value=test1", ENDITEM,//password的值如果是正确的,返回 "PASS";如果是错误的,则返回"FAIL"
"Name=JSFormSubmit", "Value=off", ENDITEM,
"Name=login.x", "Value=0", ENDITEM,
"Name=login.y", "Value=0", ENDITEM,
LAST);
web_concurrent_start(NULL);
//在该位置插入检查点
web_reg_find("Text=test1",
"SaveCount=num",//用变量num统计查找内容test1
"Search=Body",
LAST);
web_url("login.pl_2",
"URL=http://127.0.0.1:1080/WebTours/login.pl?intro=true",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/login.pl",
"Snapshot=t16.inf",
"Mode=HTTP",
LAST);
web_url("nav.pl_2",
"URL=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/login.pl",
"Snapshot=t17.inf",
"Mode=HTTP",
LAST);
web_concurrent_end(NULL);
web_concurrent_start(NULL);
web_url("flights.gif",
"URL=http://127.0.0.1:1080/WebTours/images/flights.gif",
"Resource=1",
"RecContentType=image/gif",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",
"Snapshot=t18.inf",
LAST);
web_url("itinerary.gif",
"URL=http://127.0.0.1:1080/WebTours/images/itinerary.gif",
"Resource=1",
"RecContentType=image/gif",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",
"Snapshot=t19.inf",
LAST);
web_url("signoff.gif",
"URL=http://127.0.0.1:1080/WebTours/images/signoff.gif",
"Resource=1",
"RecContentType=image/gif",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",
"Snapshot=t20.inf",
LAST);
web_url("in_home.gif",
"URL=http://127.0.0.1:1080/WebTours/images/in_home.gif",
"Resource=1",
"RecContentType=image/gif",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",
"Snapshot=t21.inf",
LAST);
web_concurrent_end(NULL);
//判断事务结束状态
if(atoi(lr_eval_string("{num}"))>=1){//判断变量num(即查找内容的次数)是否大于或等于1
lr_end_transaction("登录", LR_PASS);//如果是,则说明找到了,即登录成功,返回LR_PASS
}
else{
lr_end_transaction("登录", LR_FAIL);//否则,返回LR_FAIL
}
return 0;
}
  3、手动关联
  手动关联与前面所提到的两种自动关联不同,但原理是一样的,需要先找到需要关联的量,然后使用LR提供的关联函数进行关联。这方法是用于上面两种方法都不能解决的情况,步骤如下:
  1)录制两份脚本,保证事务流程和使用的数据相同;
  2)使用WinDiff工具比较两份脚本,找到需要关联的数据。(WinDiff是LR自带的文件比较工具)tools->compare with vuser,弹出的对话框中选择要和当前脚本进行比较的脚本,WinDiff会显示有差异的地方,每个差异的地方都可能是需要关联的地方,但是lr_think_time的差异部分是不需要关联的;
  3)找到左边界和右边界字符串;
  4)使用web_reg_save_param函数手动建立关联。首先找到关联函数插入的位置,选择vuser->run-time settings->general->log->extended log,将下面所有选项都选中。在replay log中找到windiff中比较不同的字符串,双击后,那行代码前面是为要插入关联函数的位置,如图8所示:


  
图8(关联函数插入位置)

  5)将脚本中的该关联数据以参数取代。当使用web_reg_save_param建立参数后,接下来是用参数去取代脚本中的常量,如图9所示:
  完整代码示例如下(期间遇到报错error-27216及执行失败,代码中有说明解决方法):
Action()
{
web_url("WebTours",
"URL=http://127.0.0.1:1080/WebTours",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t2.inf",
"Mode=HTTP",
LAST);
web_url("header.html",
"URL=http://127.0.0.1:1080/WebTours/header.html",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/",
"Snapshot=t3.inf",
"Mode=HTTP",
LAST);
web_url("hp_logo.png",
"URL=http://127.0.0.1:1080/WebTours/images/hp_logo.png",
"Resource=1",
"RecContentType=image/png",
"Referer=http://127.0.0.1:1080/WebTours/header.html",
"Snapshot=t5.inf",
LAST);
web_url("welcome.pl",
"URL=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/",
"Snapshot=t6.inf",
"Mode=HTTP",
LAST);
web_url("webtours.png",
"URL=http://127.0.0.1:1080/WebTours/images/webtours.png",
"Resource=1",
"RecContentType=image/png",
"Referer=http://127.0.0.1:1080/WebTours/header.html",
"Snapshot=t7.inf",
LAST);
web_url("home.html",
"URL=http://127.0.0.1:1080/WebTours/home.html",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",
"Snapshot=t11.inf",
"Mode=HTTP",
LAST);
//下面是手动写的关联函数,但是运行报错(error-27216)
//web_reg_save_param("BL",
//    "LB=userSession value=",
//    "RB=>",
//    "Search=Body",
//    LAST);
//所以尝试在树模型下插入关联函数,结果运行成功了,下面是用插入方式插入的关联函数
web_reg_save_param("BL",//创建变量BL
"LB=userSession value=",
"RB=>",
"Search=Body",
LAST);
web_url("nav.pl",
"URL=http://127.0.0.1:1080/WebTours/nav.pl?in=home",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",
"Snapshot=t12.inf",
"Mode=HTTP",
LAST);
web_url("mer_login.gif",
"URL=http://127.0.0.1:1080/WebTours/images/mer_login.gif",
"Resource=1",
"RecContentType=image/gif",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",
"Snapshot=t13.inf",
LAST);
web_concurrent_start(NULL);
web_url("8afc2fe48db9060fe1bdda2089e1d950.png",
"URL=http://act.cmcmcdn.com/upload/201507/8afc2fe48db9060fe1bdda2089e1d950.png",
"Resource=1",
"RecContentType=image/png",
"Referer=http://127.0.0.1:1080/WebTours/",
"Snapshot=t18.inf",
LAST);
web_url("3b491068507d8f85ea7b35d756da7215.png",
"URL=http://act.cmcmcdn.com/upload/201507/3b491068507d8f85ea7b35d756da7215.png",
"Resource=1",
"RecContentType=image/png",
"Referer=http://127.0.0.1:1080/WebTours/",
"Snapshot=t19.inf",
LAST);
web_concurrent_end(NULL);
lr_start_transaction("登录");
lr_think_time(15);
web_submit_data("login.pl",
"Action=http://127.0.0.1:1080/WebTours/login.pl",
"Method=POST",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",
"Snapshot=t20.inf",
"Mode=HTTP",
ITEMDATA,
//用BL变量代替常量,即value的值要改为变量值
//如果直接输入session的参数变量值时执行失败的话,可以尝试右键replace with a parameter(我有遇到这个情况)
"Name=userSession", "Value={BL}", ENDITEM,
"Name=username", "Value=test1", ENDITEM,
"Name=password", "Value=test1", ENDITEM,//password的值如果是正确的,返回 "PASS";如果是错误的,则返回"FAIL"
"Name=JSFormSubmit", "Value=off", ENDITEM,
"Name=login.x", "Value=48", ENDITEM,
"Name=login.y", "Value=13", ENDITEM,
LAST);
web_concurrent_start(NULL);
web_url("nav.pl_2",
"URL=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/login.pl",
"Snapshot=t21.inf",
"Mode=HTTP",
LAST);
//在树模型下插入的检查点
web_reg_find("Text=test1",
"SaveCount=num",//用变量num统计查找内容test1
"Search=Body",
LAST);
web_url("login.pl_2",
"URL=http://127.0.0.1:1080/WebTours/login.pl?intro=true",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/login.pl",
"Snapshot=t22.inf",
"Mode=HTTP",
LAST);
web_concurrent_end(NULL);
web_concurrent_start(NULL);
web_url("flights.gif",
"URL=http://127.0.0.1:1080/WebTours/images/flights.gif",
"Resource=1",
"RecContentType=image/gif",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",
"Snapshot=t23.inf",
LAST);
web_url("itinerary.gif",
"URL=http://127.0.0.1:1080/WebTours/images/itinerary.gif",
"Resource=1",
"RecContentType=image/gif",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",
"Snapshot=t24.inf",
LAST);
web_url("signoff.gif",
"URL=http://127.0.0.1:1080/WebTours/images/signoff.gif",
"Resource=1",
"RecContentType=image/gif",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",
"Snapshot=t25.inf",
LAST);
web_url("in_home.gif",
"URL=http://127.0.0.1:1080/WebTours/images/in_home.gif",
"Resource=1",
"RecContentType=image/gif",
"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",
"Snapshot=t26.inf",
LAST);
web_concurrent_end(NULL);
//判断事务结束状态
if(atoi(lr_eval_string("{num}"))>=1){//判断变量Num(即查找内容的次数)是否大于或等于1
lr_end_transaction("登录", LR_PASS);//如果是,则返回LR_PASS
}
else{
lr_end_transaction("登录", LR_FAIL);//否则,返回LR_FAIL
}
return 0;
}