资源描述
灵活运用LR函数编写测试脚本
想获取更多测试资料,请访问织雀教育官网。
对于一些刚学loadrunner的朋友来说,会经常遇到这样一些问题:
(1) 对于服务器返回的动态数据,不知道如何使用关联函数进行取值。
(2) 正确关联动态数据后,不知道如何对关联的数据进行字符串操作。
(3) 脚本回放不成功,不知道到底是哪里出现了问题,无法去进行有效的脚本调试。
至于第一个问题,如果你不懂,建议去网上下载相关的资料读上一百遍。本文将针对后面二个问题,结合笔者以前做过的实际案例,使用两种方法实现一些相对较复杂的动态数据关联,并如何灵活运用LR函数对这些关联后的数据进行随心所欲的操作。
1 案例背景
××银行的内部评级系统,其中有一个页面,如图:
开发人员在设计查询条件时,没有唯一识别表格记录的客户编号字段,而且表格中的记录使用一次后,就会自动删除,这样就直接导致代码回放失败。如果换成其他的客户编号,那么它在表格中的位置可能与录制时不同,关联的数据可能错误,并不是该客户对应的数据,代码也会运行失败。
但是我通过查看页面源文件,注意到这样一个特点:每个客户编号对应代码中的动态数据(需要关联的数据)都是有规律的出现。有了这个特点,我们可以通过以下步骤实现正确取值:
(1) 利用关联函数,设置函数属性Ord均为ALL,取出所有满足边界值的数据。
(2) 利用for循环和if判断语句,找出我们需要的客户编号在页面列表的第几行。
(3) 利用客户编号与其对应的数据的规律(关联函数中的Ord值规律),找出客户编号对应的关联数据值,如图:
关联函数中的Ord值规律
对应表格中
第几行数据 KeHuBianHao
_temp TYPE_temp PROCESSINSTID _temp SS_temp ChuShenYuan
_temp
第一行 10 1 2 22 61
第二行 8*1+10 3*1+1 3*1+2 4*1+22 12*1+61
第三行 8*2+10 3*2+1 3*2+2 4*2+22 12*1+61
…… ….. …… …… …… ……
(4) 利用sprinf函数和lr_save_string函数,将找出的关联数据变量转化成LR参数。
2 步骤实现的部分代码(建议:文中的代码使用VuGen查看)
根据案例背景中分析的步骤,下面我使用两种方法实现。
方法一:充分利用函数sprintf、lr_save_string、lr_eval_string进行字符串操作。代码如下:
web_reg_save_param("KeHuBianHao_SUM",
"LB=<td>",
"RB=<",
"Ord=ALL",
"RelFrameId=1",
"Search=Body",
"IgnoreRedirections=Yes",
LAST);
web_reg_save_param("TYPE_SUM",
"LB=processinfolist/PROCESSINFO[@type='",
"RB='",
"Ord=ALL",
"Search=Body",
LAST);
web_reg_save_param("PROCESSINSTID _SUM",
"LB= value=\"",
"RB=\"",
"Ord=ALL",
"Search=Body",
LAST);
web_reg_save_param("SS_SUM",
"LB= name=\"",
"RB=\"",
"Ord=ALL",
"Search=Body",
LAST);
web_reg_save_param("ChuShenYuan_SUM",
"LB=option value=\"",
"RB=\"",
"Ord=ALL",
"Search=Body",
LAST);
web_submit_data("irs_workflow2.pr.prWFWorkList.do_2",
"Action=http://182.119.171.149:9085/irs_workflow2.pr.prWFWorkList.do",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html", "Referer=http://182.119.171.149:9085/irs_workflow2.pr.prWFWorkList.do?clickCurrentMenuPath=评级->客户评级",
"Snapshot=t9.inf",
"Mode=HTML",
ITEMDATA,
"Name=VD_WFList_FP/DEPTCODE/criteria/value", "Value=", ENDITEM,
"Name=VD_WFList_FP/FIRCODE/criteria/value", "Value=", ENDITEM,
"Name=VD_WFList_FP/PRESTATE/criteria/value", "Value=", ENDITEM,
"Name=VD_WFList_FP/OPERATORNAME/criteria/value", "Value={KHJL}", ENDITEM,
"Name=VD_WFList_FP/OPERATORNAME/criteria/operator", "Value=like", ENDITEM,
"Name=VD_WFList_FP/OPERATORNAME/criteria/likeRule", "Value=center", ENDITEM,
"Name=Submit", "Value=查询", ENDITEM,
LAST);
for( xunhuan = 10;xunhuan < atoi(lr_eval_string("{KeHuBianHao_SUM _count}"));){
sprintf(buffer,"{ KeHuBianHao_SUM _%d}",xunhuan);
if ( strcmp( buffer ,lr_eval_string("{KeHuBianHao}") )){ //diedai初始值为0
TYPE_SUM_diedai = 3 * diedai + 1;
PROCESSINSTID _SUM _diedai = 3 * diedai + 2;
SS_SUM _diedai = 4 * diedai + 22;
ChuShenYuan_SUM _diedai = 12 * diedai + 61;
}
else{
lr_error_message("分派员在第%s次循环时无法找到待分派的客户编号:%s", lr_eval_string("{Itetation}"),lr_eval_string("{KeHuBianHao}"));
lr_exit(LR_EXIT_ITERATION_AND_CONTINUE,LR_FAIL);
}
diedai += 1;
xunhuan += 8;
}
sprintf(TYPE_temp, "{ TYPE_SUM _%d}", TYPE_SUM _diedai );
lr_save_string(lr_eval_string(TYPE_temp),"TYPE_VAL");
sprintf(PROCESSINSTID _temp, "{ PROCESSINSTID _SUM _%d}", PROCESSINSTID _SUM _diedai);
lr_save_string(lr_eval_string(PROCESSINSTID _temp),"PROCESSINSTID_Val");
sprintf(SS_temp, "{SS_SUM_%d}", SS_SUM_diedai);
lr_save_string(lr_eval_string(SS_temp),"SS_VAL");
sprintf(ChuShenYuan_temp, "{ ChuShenYuan_SUM _%d}", ChuShenYuan_SUM _diedai);
lr_save_string(lr_eval_string(ChuShenYuan_temp),"ChuShenYuan");
/*选择初审员,点击分发*/
web_submit_data("irs_workflow2.pr.prWF_FP_ToNext.do",
"Action=http://182.119.171.149:9085/irs_workflow2.pr.prWF_FP_ToNext.do?PR
OCESSINFO/OPERATE=-1",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http://182.119.171.149:9085/irs_workflow2.pr.prWFWorkList.do",
"Snapshot=t10.inf",
"Mode=HTML",
ITEMDATA,
"Name=VD_WFList_FP/PRESTATE/criteria/value", "Value=", ENDITEM,
"Name=VD_WFList_FP/FIRCODE/criteria/value", "Value=", ENDITEM,
"Name=VD_WFList_FP/OPERATORNAME/criteria/value", "Value={KHJL}", ENDITEM,
"Name=VD_WFList_FP/OPERATORNAME/criteria/operator", "Value=like", ENDITEM,
"Name=VD_WFList_FP/OPERATORNAME/criteria/likeRule", "Value=center", ENDITEM,
"Name=VD_WFList_FP/DEPTCODE/criteria/value", "Value=", ENDITEM,
"Name=VD_WFList_FP/PREVALID", "Value=1", ENDITEM,
"Name=processinfolist/PROCESSINFO[@type='{TYPE_VAL}']/
PROCESSINSTID", "Value={PROCESSINSTID_Val}", ENDITEM,
"Name=processinfolist/PROCESSINFO[@type='{TYPE_VAL}']/WORKITEMID", "Value={TYPE_VAL}", ENDITEM,
"Name={SS_VAL}", "Value=0 ", ENDITEM,
"Name=processinfolist/PROCESSINFO[@type='{TYPE_VAL}']/OPERATORID", "Value={ ChuShenYuan }", ENDITEM,
LAST);
从以上代码,我们可以看出:
(1) 先通过for循环,遍历所有的客户编号关联值,在每次循环时,使用sprintf函数将客户编号(KeHuBianHao_SUM _xunhuan)转化成LR变量buffer。
(2) 然后使用if判断buffer与正确的客户编号是否相等,找出正确的客户编号需要的迭代次数(daidie)。
(3) 根据if判断出的daidie值,以及各关联值Ord的规律,确定出各参数的Ord值。
(4) 再使用sprintf、lr_save_string函数,将各关联变量值转化成LR参数为TYPE_VAL、PROCESSINSTID_Val、SS_VAL、ChuShenYuan。
方法二:充分利用函数sprintf、lr_eval_string进行字符串操作。代码如下:
for( xunhuan = 10;xunhuan < atoi(lr_eval_string("{KeHuBianHao_SUM _count}"));){
sprintf(buffer,"{ KeHuBianHao_SUM _%d}",xunhuan);
if ( strcmp( buffer ,lr_eval_string("{KeHuBianHao}") )){ //diedai初始值为0
TYPE_SUM_diedai = 3 * diedai + 1;
PROCESSINSTID _SUM _diedai = 3 * diedai + 2;
SS_SUM _diedai = 4 * diedai + 22;
ChuShenYuan_SUM _diedai = 12 * diedai + 61;
}
else{
lr_error_message("分派员在第%s次循环时无法找到待分派的客户编号:%s", lr_eval_string("{Itetation}"),lr_eval_string("{KeHuBianHao}"));
lr_exit(LR_EXIT_ITERATION_AND_CONTINUE,LR_FAIL);
}
diedai += 1;
xunhuan += 8;
}
sprintf(TYPE_temp, "{ TYPE_SUM _%d}", TYPE_SUM _diedai );
sprintf(PROCESSINSTID,"Name=processinfolist/PROCESSINFO[@type='%s']/
PROCESSINSTID", lr_eval_string(TYPE_temp));
sprintf(WORKITEMID,"Name=processinfolist/PROCESSINFO[@type='%s']/
WORKITEMID", lr_eval_string(TYPE_temp));
sprintf(WORKITEMID_Value, "Value=%s", lr_eval_string(TYPE_temp));
sprintf(PROCESSINSTID _temp, "{ PROCESSINSTID _SUM _%d}",
PROCESSINSTID _SUM _diedai);
sprintf(PROCESSINSTID_Value, "Value=%s", lr_eval_string(PROCESSINSTID
_temp));
sprintf(SS_temp, "{SS_SUM_%d}", SS_SUM_diedai);
sprintf(SSVal, "Name=%s", lr_eval_string(SS_temp));
sprintf(ChuShenYuan_temp, "{ ChuShenYuan_SUM _%d}", ChuShenYuan_SUM _diedai);
sprintf(OPERATORID_Value, "Value=%s", lr_eval_string(ChuShenYuan_temp));
/*选择初审员,点击分发*/
web_submit_data("irs_workflow2.pr.prWF_FP_ToNext.do",
"Action=http://182.119.171.149:9085/irs_workflow2.pr.prWF_FP_ToNext.do?PROCESSINFO/OPERATE=-1",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http://182.119.171.149:9085/irs_workflow2.pr.prWFWorkList.do",
"Snapshot=t10.inf",
"Mode=HTML",
ITEMDATA,
PROCESSINSTID , PROCESSINSTID_Value, ENDITEM,
WORKITEMID , WORKITEMID_Value, ENDITEM,
SSVal , "Value=0 ", ENDITEM,
OPERATORID , OPERATORID_Value, ENDITEM,
LAST);
从以上代码,我们可以看出:方法二没有使用lr_save_string将LR变量转化成参数,而是两次使用sprintf函数构造LR变量PROCESSINSTID、PROCESSINSTID_Value、WORKITEMID、WORKITEMID_Value、SSVal、OPERATORID、OPERATORID_Value,并直接作为web_submit_data函数中的ITEMDATA。
3 知识总结
(1) 关联函数web_reg_save_param的使用方法,重点理解其中一个属性Ord值。它表示第几次出现的左边界子串的匹配项才是需要的内容。该属性可有可无,缺省值是1。如为All,则将所有找到的内容储存起来。本文中的全部关联Ord设置为All,因为Ord不确定。只有先全部取出,然后通过判断取出我们需要的值。
(2) 如何找出各关联值之间的联系,即本文中的Ord值规律。其实找出这个规律很简单:
第一步:大家可以先设置关联函数的Ord值为All,
第二步:在调试代码之前,设置run-time setting中的Log为Extended Log及parameters substitution,
第三步:运行代码,从Replay log中记录每一个有效的关联值的Ord值,
通过以上三步,就可以找出Ord值规律。不信,您可以试试,会有惊喜!
(4) lr_save_string函数的使用方法。它的功能是将LR代码中的常量或变量保存为lr中的参数。具体的函数用法,我就不讲了,详见LR中help文档。
(5) LR中常用的字符串操作的函数。具体有以下几个常见的函数:strcpy、strcat、
strcmp、itoa、atoi、atof、atol。这里值得注意的是atof、atol在使用之前一定要先对其进行声明,具体使用方法,请参考LR中help文档。
(6) lr_eval_string函数的使用方法。任何C的变量都不能被LR的函数直接调用,
应该用lr_eval_string来取值。
(7) sprintf函数的使用方法。它是一个格式化输出函数,格式化输出到字符串中。
(8) 在文中的第二种方法中,我们将多个LR变量值直接运用到web_submit_data函数的ITEMDATA中,这样大大简化了代码,使得代码有更强的可读性。
(9) 从文中关于关联函数的使用,我们可以延伸出其他用法:
第一种延伸:可以通过关联取出满足左边界值的最后一个值,具体代码如下
web_reg_save_param("Param" , "LB=<td>" , "RB=<" , "Ord=ALL" , LAST);
web_url("HomePage", "URL=<Your_URL>", LAST);
Sprintf( Last_Param , ”{Param_%s}” , lr_eval_string(“{Param _count}”));
lr_output_string(“Param的最后一个值为:%s” , Last_Param);
第二种延伸:可以通过关联取出满足左边界值的随机值,具体代码如下:
char i = NULL;
int j = 0;
web_reg_save_param("Param" , "LB=<td>" , "RB=<" , "Ord=ALL" , LAST);
web_url("HomePage", "URL=<Your_URL>", LAST);
j = atoi(lr_eval_string("{Param_count}"));
sprintf(&i, "%d", ( 1 + rand() % j));
lr_save_string(&i, "random_value");
temp = lr_eval_string(lr_eval_string("{Param_{random_value}}"));
lr_save_string(temp, "Random_Param");
lr_output_string(“Param的一个随即值为:%s” ,lr_eval_string("{Random_Param}"));
(10) 关于代码调试。在编写测试代码时,会遇到很多难以预料的问题,比如说,使用盗版LR的原因、测试机的原因、人为的原因等等,都会导致代码运行失败,而且有些失败原因是无法在Replay log呈现的,我们仅仅从代码本身去定位问题是很难的。像遇到这种情况,笔者比较偏爱几个日志打印函数:lr_output_message、lr_log_message、lr_message。通过这几个函数,我们可以时时跟踪代码走向,步步跟踪变量值的变化情况,做到运行脚本有的放矢,一切都在自己掌握之中。
4 结束语
本文介绍的所有这些函数使用技巧,在网络中都可以很容易地查到,笔者只是根据自己的使用经验,结合实际案例,把一些网络上零散的、常用的、有用的东西进行了概括总结。或许本文对你毫无价值,那就当做是一个乐子,一看而过罢了;或许对于一些LR新手和一些不太熟练操作LR函数的朋友来说,本文对你们会有很大的启发,笔者希望对你们以后学习loadrunner有一定指导意义,共同推进国内测试的发展。
展开阅读全文