0


【测试技术-性能测试-实战1】使用Loadrunner自带的系统学习脚本编写和脚本增强。

1、启动Web Tours Server

  • Hp software->start hp web tours server
  • Hp software->hp web tours application

2、脚本录制

2.1、录制前设置

  • 打开Virtual User Generator
  • 创建脚本,协议选择Web - HTTP/HTML,输入脚本名,选择好脚本存放路径,点击create即可创建好一个空白脚本。
  • 设置录制选项,点击record按钮,设置完基本信息后,点击右下角的Recording Options,设置录制选项:- HTTP/HTML Level设置:使用基于HTML-based script录制的脚本更简洁欸,使用基于URL-based script录制的脚本,会将每个html元素都使用web_url函数加载,脚本冗长,不易关联。实际使用时基于浏览器的的应用程序(未使用HTTP安全协议)推荐选择HTML-based script;非浏览器/使用了HTTPS安全协议,推荐使用URL-based script。- 编码设置(防止录制出现中文乱码):HTTP Properties -> Advanced,勾选上Support charset(UTF-8)- 其他使用默认选项即可
  • 开始录制:录制选项设置完成后,点击Start Recording即可开始录制。

2.2、开始录制

录制完整的登录->查询航班->选择航班->支付->查看结果->退出登录流程

2.2.1、登录

登录之前先插入一个登录事务:tran01_login,然后输入用户/密码(jojo/bean),点击登录:

在这里插入图片描述

登录完成后,结束登录事务:

在这里插入图片描述

2.2.2、查找航班

先点击页面上的Flights,进入查找航班界面,然后插入事务:tran02_findFlight,输入航班信息后,点击continue按钮进入下一步

在这里插入图片描述

点击按钮后,结束tran02_findFlight事务。

2.2.3、选择航班

插入事务:trans03_selectFlight,选择航班,然后点击continue,进入下一步

在这里插入图片描述

结束trans03_selectFlight事务

2.2.4、支付

插入事务:trans04_payment,输入支付信息后,然后点击continue,进入下一步

在这里插入图片描述

结束trans04_payment事务

2.2.5、查看结果

插入事务:trans05_itinerary,点击Itinerary,查看预定结果

在这里插入图片描述

结束trans05_itinerary事务

2.2.6、退出登录

插入事务:trans06_signOff,点击sign Off按钮退出登录:

在这里插入图片描述

结束trans06_signOff事务。

至此,整个预定流程完成,点击结束录制按钮,完成录制,生成录制脚本。

完整的录制脚本如下:

Action(){//打开WebTours主页web_url("index.htm","URL=http://127.0.0.1:1080/WebTours/index.htm","Resource=0","RecContentType=text/html","Referer=","Snapshot=t1.inf","Mode=HTML", 
        LAST);lr_think_time(13);//登录lr_start_transaction("tran01_login");web_submit_data("login.pl","Action=http://127.0.0.1:1080/cgi-bin/login.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/nav.pl?in=home","Snapshot=t4.inf","Mode=HTML", 
        ITEMDATA,"Name=userSession","Value=133951.489509923ziQAVcQpHtVzzzzHtVDtApHHitf", ENDITEM,"Name=username","Value=jojo", ENDITEM,"Name=password","Value=bean", ENDITEM,"Name=JSFormSubmit","Value=on", ENDITEM,"Name=login.x","Value=51", ENDITEM,"Name=login.y","Value=10", ENDITEM, 
        LAST);lr_end_transaction("tran01_login",LR_AUTO);lr_think_time(13);//查询航班lr_start_transaction("tran02_findFlight");web_submit_data("reservations.pl","Action=http://127.0.0.1:1080/cgi-bin/reservations.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/reservations.pl?page=welcome","Snapshot=t9.inf","Mode=HTML", 
        ITEMDATA,"Name=advanceDiscount","Value=0", ENDITEM,"Name=depart","Value=Denver", ENDITEM,"Name=departDate","Value=05/28/2022", ENDITEM,"Name=arrive","Value=Frankfurt", ENDITEM,"Name=returnDate","Value=05/29/2022", ENDITEM,"Name=numPassengers","Value=1", ENDITEM,"Name=seatPref","Value=Window", ENDITEM,"Name=seatType","Value=First", ENDITEM,"Name=.cgifields","Value=roundtrip", ENDITEM,"Name=.cgifields","Value=seatType", ENDITEM,"Name=.cgifields","Value=seatPref", ENDITEM,"Name=findFlights.x","Value=65", ENDITEM,"Name=findFlights.y","Value=5", ENDITEM, 
        LAST);lr_end_transaction("tran02_findFlight",LR_AUTO);lr_think_time(21);//选择航班lr_start_transaction("trans03_selectFlight");web_submit_data("reservations.pl_2","Action=http://127.0.0.1:1080/cgi-bin/reservations.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/reservations.pl","Snapshot=t10.inf","Mode=HTML", 
        ITEMDATA,"Name=outboundFlight","Value=013;592;05/28/2022", ENDITEM,"Name=numPassengers","Value=1", ENDITEM,"Name=advanceDiscount","Value=0", ENDITEM,"Name=seatType","Value=First", ENDITEM,"Name=seatPref","Value=Window", ENDITEM,"Name=reserveFlights.x","Value=52", ENDITEM,"Name=reserveFlights.y","Value=9", ENDITEM, 
        LAST);lr_end_transaction("trans03_selectFlight",LR_AUTO);lr_think_time(26);//支付lr_start_transaction("trans04_payment");web_submit_data("reservations.pl_3","Action=http://127.0.0.1:1080/cgi-bin/reservations.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/reservations.pl","Snapshot=t11.inf","Mode=HTML", 
        ITEMDATA,"Name=firstName","Value=Jojo", ENDITEM,"Name=lastName","Value=Bean", ENDITEM,"Name=address1","Value=123", ENDITEM,"Name=address2","Value=456", ENDITEM,"Name=pass1","Value=Jojo Bean", ENDITEM,"Name=creditCard","Value=123456", ENDITEM,"Name=expDate","Value=1122", ENDITEM,"Name=saveCC","Value=on", ENDITEM,"Name=oldCCOption","Value=on", ENDITEM,"Name=numPassengers","Value=1", ENDITEM,"Name=seatType","Value=First", ENDITEM,"Name=seatPref","Value=Window", ENDITEM,"Name=outboundFlight","Value=013;592;05/28/2022", ENDITEM,"Name=advanceDiscount","Value=0", ENDITEM,"Name=returnFlight","Value=", ENDITEM,"Name=JSFormSubmit","Value=off", ENDITEM,"Name=.cgifields","Value=saveCC", ENDITEM,"Name=buyFlights.x","Value=42", ENDITEM,"Name=buyFlights.y","Value=10", ENDITEM, 
        LAST);lr_end_transaction("trans04_payment",LR_AUTO);lr_think_time(16);//查询预定结果lr_start_transaction("trans05_itinerary");web_url("welcome.pl","URL=http://127.0.0.1:1080/cgi-bin/welcome.pl?page=itinerary","Resource=0","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/nav.pl?page=menu&in=flights","Snapshot=t12.inf","Mode=HTML", 
        LAST);lr_end_transaction("trans05_itinerary",LR_AUTO);lr_think_time(19);//退出登录lr_start_transaction("trans06_signOff");web_url("welcome.pl_3","URL=http://127.0.0.1:1080/cgi-bin/welcome.pl?signOff=1","Resource=0","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/nav.pl?page=menu&in=itinerary","Snapshot=t13.inf","Mode=HTML", 
        LAST);lr_end_transaction("trans06_signOff",LR_AUTO);return0;}

3、脚本回放

点击Replay,回放脚本:

在这里插入图片描述
脚本回放成功。

4、脚本增强

4.1、参数关联

作用:将服务器返回给客户端的动态值进行关联。

回放成功后,可以登录WebTours查看预定的记录是否增加了一条,如果增加了,说明脚本没问题,可以成功预定。然而登录后,发现预定的数量并没有增加。所以,需要重新检查脚本。

首先是检查登录是否成功。可以看到登录的web_submit_data方法中,提交的参数有userSession,userSession为动态为动态生成,userSession在第一次请求服务器的时候有服务器返回,所以需要对该参数做参数关联。

要获取userSession有两个方法:

  • 在浏览器中请求页面,F12工具查看返回,在响应报文中查找userSession:

在这里插入图片描述

可以看到nav.pl?in=home请求中,返回报文中包含userSession:

<inputtype="hidden"name="userSession"value="133944.089590928ziiQHtQpVAiDDDDDtVDDiptQtzf"/>
  • 在Loadrunner中,请求的上一步操作的任一地方,点击右键->Show snapshot,然后在Snapshot中使用Ctrl+F查找该值,同样可以找到:

在这里插入图片描述
在这里插入图片描述

找到userSession后,即可开始编写关联函数,关联函数为web_reg_save_param(),具体如下:

//设置userSession参数关联web_reg_save_param("userSession",//参数名"LB=name=\"userSession\" value=\"",//左边界:参数值的左边字符,如果带有双引号,需要用\进行转义"RB=\"/>",//右边界:参数值的右边字符,根据左右边界可以唯一确定参数值
                   LAST);

注意关联需要写到操作函数的上面,关联函数编写完成后,需要替换脚本中的参数值,将登录时的提交参数替换如下:

web_submit_data("login.pl","Action=http://127.0.0.1:1080/cgi-bin/login.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/nav.pl?in=home","Snapshot=t42.inf","Mode=HTML", 
                ITEMDATA,"Name=userSession","Value={userSession}", ENDITEM,//参数关联,参数名需要用{}括起来"Name=username","Value=jojo", ENDITEM,"Name=password","Value=bean", ENDITEM,"Name=JSFormSubmit","Value=on", ENDITEM,"Name=login.x","Value=42", ENDITEM,"Name=login.y","Value=12", ENDITEM, 
                LAST);

关联完成后,重新回放,然后登录网站检查,可以看到Itinerary中订单多了一个记录,每回放一次都会多一条,说明关联成功,脚本可以正常完成登录了。

4.2、参数化

在该脚本中,所有参数均是固定的,比如订票操作,每次都是订的Denver->Frankfurt,如果想要每次预定都使用不同的出发/到达城市对,则需要进行对响应的数据进行参数化,具体操作参考:https://blog.csdn.net/weixin_42115131/article/details/124965795

设置好的脚本如下:

web_submit_data("reservations.pl","Action=http://127.0.0.1:1080/cgi-bin/reservations.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/reservations.pl?page=welcome","Snapshot=t47.inf","Mode=HTML", 
                ITEMDATA,"Name=advanceDiscount","Value=0", ENDITEM,"Name=depart","Value={depart}", ENDITEM,//出发城市参数化"Name=departDate","Value=05/27/2022", ENDITEM,"Name=arrive","Value={arrive}", ENDITEM,//到达城市参数化"Name=returnDate","Value=05/28/2022", ENDITEM,"Name=numPassengers","Value=1", ENDITEM,"Name=seatPref","Value=Window", ENDITEM,"Name=seatType","Value=Business", ENDITEM,"Name=.cgifields","Value=roundtrip", ENDITEM,"Name=.cgifields","Value=seatType", ENDITEM,"Name=.cgifields","Value=seatPref", ENDITEM,"Name=findFlights.x","Value=63", ENDITEM,"Name=findFlights.y","Value=8", ENDITEM, 
                LAST);

参数值在Parameters中可以进行设置。
在这里插入图片描述

参数设置时,Select next row框选取Unique和Sequential有如下区别,以10个虚拟用户迭代10次为例:

当选择Sequential时,可以看到,同一个每个虚拟用户取值相同,下一次迭代取第二个参数,第6次迭代参数已取完,重新循环取第一个值:

在这里插入图片描述

当选择Unique时,表示每个虚拟用户取唯一的一个值,每次迭代每个虚拟用户都会取不同参数值,由于只设置了5个虚拟用户,所以后5个虚拟用户未取到值:

在这里插入图片描述

替换参数后,重新运行脚本,在runtime setting中将迭代设置为5次,完成后登录网站查看是否生成了5个不同城市对的订单

在这里插入图片描述

可以看出,生成的5个记录全是Denver/Frankfurt。参数化并未生效。

再次检查脚本,发现查询航班完成后的选择航班提交的数据,outboundFlight为013;592;05/28/2022,即不论查询结果是什么,每次选择的航班都是013号,592$,该值为查询航班时由服务器返回的值,所以,还需要对该值做参数关联,关联方法同userSession:

web_reg_save_param("outboundFlight","LB=name=\"outboundFlight\" value=\"","RB=\">","Ord=2",//相同的左右边界共有4个,取第二个
                   LAST);

关联之后,把后面脚本中出现该参数的地方都用关联的参数替换掉,然后重新执行脚本,检查结果:

在这里插入图片描述

可以看到,成功预定了5张不同出发到达城市对的票。

4.3、检查点设置

订票成功后,页面上会返回字符串”Thank you for booking through Web Tours.“,这儿介绍两种设置检查点的方法:

4.3.1、web_reg_find()函数

参考:https://blog.csdn.net/weixin_42115131/article/details/124965795

4.3.2、保存&对比

原理和参数关联一致,先将服务器返回的参数保存下来:

<small><B>Thank you for booking through Web Tours.</B></small>
web_reg_save_param("response","LB=<small><B>","RB=</B></small>",
                   LAST);

在payment之后,对服务器返回值和预期值做对比:

//检查支付是否成功if(strstr(lr_eval_string("{payment_result}"),"Thank you for booking through Web Tours.")!=NULL){//strstr(str1, str2)为c语言函数,如果str2为str1子串,则返回字串出现的位置;不是则返回NULL//lr_eval_string()函数作用为返回脚本中的一个参数当前的值,格式为:lr_eval_string("{参数名}");lr_end_transaction("trans04_payment",LR_PASS);//事务有3种结束状态,LR_AUTO为自动结束,不判断成功失败;LR_FAIL为以失败的状态结束;LR_PASS为以成功的状态结束           lr_output_message("Success! depart is %s, arrive is %s.",lr_eval_string("{depart}"),lr_eval_string("{arrive}"));//lr_output_message为打印函数}else{lr_end_transaction("trans04_payment",LR_PASS);lr_output_message("FAIL!!!!!!");}

加入检查点后,重新运行,结果如下:

Action.c(149): Success! depart is Portland, arrive is Denver.
Action.c(149): Success! depart is San Francisco, arrive is Frankfurt.
Action.c(149): Success! depart is Seattle, arrive is London.
Action.c(149): Success! depart is Sydney, arrive is Los Angeles.
Action.c(149): Success! depart is Zurich, arrive is Paris.

至此,脚本调试完成,可以将脚本加载到controller中设置场景执行。完整脚本如下:

Action(){//设置userSession参数关联web_reg_save_param("userSession",//参数名"LB=name=\"userSession\" value=\"",//左边界:参数值的左边字符,如果带有双引号,需要用\进行转义"RB=\"/>",//右边界:参数值的右边字符,根据左右边界可以唯一确定参数值
        LAST);//打开WebTours主页web_url("index.htm","URL=http://127.0.0.1:1080/WebTours/index.htm","Resource=0","RecContentType=text/html","Referer=","Snapshot=t1.inf","Mode=HTML", 
        LAST);lr_think_time(13);//登录lr_start_transaction("tran01_login");web_submit_data("login.pl","Action=http://127.0.0.1:1080/cgi-bin/login.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/nav.pl?in=home","Snapshot=t4.inf","Mode=HTML", 
        ITEMDATA,"Name=userSession","Value={userSession}", ENDITEM,"Name=username","Value=jojo", ENDITEM,"Name=password","Value=bean", ENDITEM,"Name=JSFormSubmit","Value=on", ENDITEM,"Name=login.x","Value=51", ENDITEM,"Name=login.y","Value=10", ENDITEM, 
        LAST);lr_end_transaction("tran01_login",LR_AUTO);lr_think_time(13);//查询航班lr_start_transaction("tran02_findFlight");//设置outboundFlight关联函数web_reg_save_param("outboundFlight","LB=name=\"outboundFlight\" value=\"","RB=\">","Ord=2",//相同的左右边界共有4个,取第二个
       LAST);web_submit_data("reservations.pl","Action=http://127.0.0.1:1080/cgi-bin/reservations.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/reservations.pl?page=welcome","Snapshot=t9.inf","Mode=HTML", 
        ITEMDATA,"Name=advanceDiscount","Value=0", ENDITEM,"Name=depart","Value={depart}", ENDITEM,"Name=departDate","Value=05/28/2022", ENDITEM,"Name=arrive","Value={arrive}", ENDITEM,"Name=returnDate","Value=05/29/2022", ENDITEM,"Name=numPassengers","Value=1", ENDITEM,"Name=seatPref","Value=Window", ENDITEM,"Name=seatType","Value=First", ENDITEM,"Name=.cgifields","Value=roundtrip", ENDITEM,"Name=.cgifields","Value=seatType", ENDITEM,"Name=.cgifields","Value=seatPref", ENDITEM,"Name=findFlights.x","Value=65", ENDITEM,"Name=findFlights.y","Value=5", ENDITEM, 
        LAST);lr_end_transaction("tran02_findFlight",LR_AUTO);lr_think_time(21);//选择航班lr_start_transaction("trans03_selectFlight");web_submit_data("reservations.pl_2","Action=http://127.0.0.1:1080/cgi-bin/reservations.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/reservations.pl","Snapshot=t10.inf","Mode=HTML", 
        ITEMDATA,"Name=outboundFlight","Value={outboundFlight}", ENDITEM,"Name=numPassengers","Value=1", ENDITEM,"Name=advanceDiscount","Value=0", ENDITEM,"Name=seatType","Value=First", ENDITEM,"Name=seatPref","Value=Window", ENDITEM,"Name=reserveFlights.x","Value=52", ENDITEM,"Name=reserveFlights.y","Value=9", ENDITEM, 
        LAST);lr_end_transaction("trans03_selectFlight",LR_AUTO);lr_think_time(26);//支付lr_start_transaction("trans04_payment");//保存返回的参数,做事务状态检查web_reg_save_param("payment_result","LB=<small><B>","RB=</B></small>",
       LAST);web_submit_data("reservations.pl_3","Action=http://127.0.0.1:1080/cgi-bin/reservations.pl","Method=POST","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/reservations.pl","Snapshot=t11.inf","Mode=HTML", 
        ITEMDATA,"Name=firstName","Value=Jojo", ENDITEM,"Name=lastName","Value=Bean", ENDITEM,"Name=address1","Value=123", ENDITEM,"Name=address2","Value=456", ENDITEM,"Name=pass1","Value=Jojo Bean", ENDITEM,"Name=creditCard","Value=123456", ENDITEM,"Name=expDate","Value=1122", ENDITEM,"Name=saveCC","Value=on", ENDITEM,"Name=oldCCOption","Value=on", ENDITEM,"Name=numPassengers","Value=1", ENDITEM,"Name=seatType","Value=First", ENDITEM,"Name=seatPref","Value=Window", ENDITEM,"Name=outboundFlight","Value={outboundFlight}", ENDITEM,"Name=advanceDiscount","Value=0", ENDITEM,"Name=returnFlight","Value=", ENDITEM,"Name=JSFormSubmit","Value=off", ENDITEM,"Name=.cgifields","Value=saveCC", ENDITEM,"Name=buyFlights.x","Value=42", ENDITEM,"Name=buyFlights.y","Value=10", ENDITEM, 
        LAST);//检查支付是否成功if(strstr(lr_eval_string("{payment_result}"),"Thank you for booking through Web Tours.")!=NULL){//strstr(str1, str2)为c语言函数,如果str2为str1子串,则返回字串出现的位置;不是则返回NULL//lr_eval_string()函数作用为返回脚本中的一个参数当前的值,格式为:lr_eval_string("{参数名}");lr_end_transaction("trans04_payment",LR_PASS);//事务有3种结束状态,LR_AUTO为自动结束,不判断成功失败;LR_FAIL为以失败的状态结束;LR_PASS为以成功的状态结束           lr_output_message("Success! depart is %s, arrive is %s.",lr_eval_string("{depart}"),lr_eval_string("{arrive}"));//lr_output_message为打印函数}else{lr_end_transaction("trans04_payment",LR_PASS);lr_output_message("FAIL!!!!!!");}lr_think_time(16);//查询预定结果lr_start_transaction("trans05_itinerary");web_url("welcome.pl","URL=http://127.0.0.1:1080/cgi-bin/welcome.pl?page=itinerary","Resource=0","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/nav.pl?page=menu&in=flights","Snapshot=t12.inf","Mode=HTML", 
        LAST);lr_end_transaction("trans05_itinerary",LR_AUTO);lr_think_time(19);//退出登录lr_start_transaction("trans06_signOff");web_url("welcome.pl_3","URL=http://127.0.0.1:1080/cgi-bin/welcome.pl?signOff=1","Resource=0","RecContentType=text/html","Referer=http://127.0.0.1:1080/cgi-bin/nav.pl?page=menu&in=itinerary","Snapshot=t13.inf","Mode=HTML", 
        LAST);lr_end_transaction("trans06_signOff",LR_AUTO);return0;}

本文转载自: https://blog.csdn.net/weixin_42115131/article/details/125007318
版权归原作者 zwhnsh 所有, 如有侵权,请联系我们删除。

“【测试技术-性能测试-实战1】使用Loadrunner自带的系统学习脚本编写和脚本增强。”的评论:

还没有评论