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;}
版权归原作者 zwhnsh 所有, 如有侵权,请联系我们删除。