一、web_custom_request函数介绍
LoadRunner提供的web_custom_request函数可以用于实现参数的动态生成。在LoadRunner中,web_reg_save_param和custom_request都常于处理参数的动态生成。
web_reg_save_param函数是大家都已经熟悉的了,它的主要作用是从一个response中获得后续的request需要使用的数据,然后将其作为一个参数保存下来,供后续步骤使用。该方法在LoadRunner中被称为Correlation(关联)。
而web_custom_request函数则可以用于完全自定义向服务端发送的request
web_custom_request方法的原型是:
int web_custom_request (const char *RequestName, <List of Attributes>,[EXTRARES, <List of Resource Attributes>,] LAST );其中List of Attributes的主要项目是Method,URL和BODY等.
下面再介绍两个事例:
/* 脚本名称:web_custom_request事例 脚本功能:通过登录WebTours的操作来演示web_custom_request函数的使用 使用的技术:关联和检查点 */ Action() { //定义一个变量,进行判断是否登录成功时使用 int tag=0; //对userSession进行关联 // <input type=hidden name=userSession value=110044.482462535fzzAtVDpAzzzzzzHDDQzcptHit> web_reg_save_param("userID","LB=<input type=hidden name=userSession value=","RB=>",LAST); web_url("WebTours", "URL=http://127.0.0.1:1080/WebTours/", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTML", LAST); lr_think_time(9); //检查点设置 tag=web_reg_find("Text=jojo","Search=ALL",LAST); /*利用web_custom_request函数自定义请求*/ web_custom_request("login.pl", "Method=POST", "URL=http://127.0.0.1:1080/WebTours/login.pl", "Body=userSession={userID}&username=jojo&password=bean&JSFormSubmit=off&login.x=54&login.y=8", LAST); if(tag==0) lr_output_message("login successful!"); else lr_output_message("login failed"); /* web_submit_form("login.pl", "Snapshot=t2.inf", ITEMDATA, "Name=username", "Value=jojo", ENDITEM, "Name=password", "Value=bean", ENDITEM, "Name=login.x", "Value=54", ENDITEM, "Name=login.y", "Value=8", ENDITEM, LAST); */ web_image("SignOff Button", "Alt=SignOff Button", "Snapshot=t3.inf", LAST); lr_output_message("signoff successful"); return 0; }
Action() { char creq[500]; web_reg_save_param("fID1", "LB=INPUT TYPE=\"hidden\" NAME=\"flightID\" VALUE=\"", "RB=\"", "ORD=1", "SEARCH=BODY", LAST); web_reg_save_param("fID2", "LB=INPUT TYPE=\"hidden\" NAME=\"flightID\" VALUE=\"", "RB=\"", "ORD=2", "SEARCH=BODY", LAST); web_url("welcome.pl", "URL=http://localhost/MercuryWebTours/welcome.pl?page=itinerary", "Resource=0", "RecContentType=text/html", "Referer=http://localhost/MercuryWebTours/nav.pl?page=menu&in=home", "Snapshot=t3.inf", "Mode=HTML", EXTRARES, "URL=images/in_itinerary.gif", "Referer=http://localhost/MercuryWebTours/nav.pl?page=menu&in=itinerary", ENDITEM, "URL=images/home.gif", "Referer=http://localhost/MercuryWebTours/nav.pl?page=menu&in=itinerary", ENDITEM, LAST); lr_think_time(2); strcpy(creq, "Body=1=on&flightID="); strcat(creq, lr_eval_string("{fID1}")); strcat(creq, "&2=on&flightID="); strcat(creq, lr_eval_string("{fID2}")); strcat(creq, "&.cgifields=1&.cgifields=2"); strcat(creq, "&removeFlights.x=116&removeFlights.y=8"); lr_output_message(creq); web_custom_request("itinerary.pl", "Method=POST", "URL=http://localhost/MercuryWebTours/itinerary.pl", "RecContentType=text/xml", creq, "Snapshot=t4.inf", LAST); return 0; }
二、LoadRunner中web_custom_request 和 web_submit_data的差别
web_custom_request方法可以发送POST和GET类型的请求
web_submit_data方法只能发送POST类型的请求
所有web_submit_data方法发送的请求都可以使用web_custom_request来实现,web_custom_request可以实现web_submit_data无法实现的请求
比如“查询所有邮件并删除”这个案例中,查询时我们使用关联把所有邮件对应的标识抓取成一个数组,如果使用web_submit_data来完成这个删除的请求,需要很多个web_submit_data请求才能完成,但使用web_custom_request就可以通过一个请求完成,方法是自己写代码拼一个web_custom_request 方法POST请求的Body值。
web_submit_data请求中提交的数据是以这样的方式存在的
“Name=属性名称,”,“Value=属性值”
“Name=dataCenter”, “Value=yh”, ENDITEM,
“Name=username”, “Value=12044″, ENDITEM,
如果我们想提交的某个属性包含包含多个值(上文的例子中就是这样的情况),它就无法处理了,只能通过多个web_submit_data来处理。
下面是一个典型的web_submit_data和web_custom_request请求,可以看到web_custom_request中提交的数据(body)是以这样的方式存在的
“Body=属性名称=属性值&属性名称=属性值&……”
“Action=http://192.168.14.21:78……ndex_sso.jsp”,
“Method=POST”,
“RecContentType=text/html”,
“Referer=http://192.168.14.21:7888…=/index_sso.jsp”,
“Mode=HTML”,
ITEMDATA,
“Name=locale”, “Value=L2″, ENDITEM,
“Name=dataCenter”, “Value=yh”, ENDITEM,
“Name=username”, “Value=12044″, ENDITEM,
“Name=password”, “Value=”, ENDITEM,
“Name=_eventId”, “Value=submit”, ENDITEM,
“Name=isPureWeb”, “Value=true”, ENDITEM,
“Name=solutionName”, “Value=eas”, ENDITEM,
“Name=dbType”, “Value=1″, ENDITEM,
“Name=easSessionId”, “Value=eas;yh;L2;12044;BaseDB”, ENDITEM,
“Name=userAuthPattern”, “Value=BaseDB”, ENDITEM,
“Name=loginFlow”, “Value=true”, ENDITEM,
LAST);
web_custom_request(“CommonQueryDialog.jsf_3″,
“URL=http://192.168.14.21:7888/ea…ueryDialog.jsf”,
“Method=POST”,
“Resource=0″,
“RecContentType=text/javascript”,
“Referer=http://192.168.14.21:7888/…DailyLoanUERc+ihtml”,
“Mode=HTML”,
“EncType=application/x-www-form-urlencoded;charset=UTF-8″,
“Body=queryDialog:selectSolutionList=查询&queryDialog:j_iduserFilterPanel_3_value=Kd5QoAEPEADgAAf8wKgEDMznrtQ=&=湖南亚华乳业有限公司&queryDialog:j_iduserFilterPanel_6=&queryDialog:j_iduserFilterPanel_9_value=3&=大于等于&queryDialog:j_iduserFilterPanel_11=0&queryDialog:j_iduserFilterPanel_14_value=&=&queryDialog:j_iduserFilterPanel_17_value=&=&queryDialog:j_iduserFilterPanel_20_value=&=&queryDialog:j_iduserFilterPanel_23_value=&=&queryDialog:j_iduserFilterPanel_26_value=&=&queryDialog:j_iduserFilterPanel_29_value=&=&queryDialog:j_iduserFilterPanel_32=&queryDialog:j_iduserFilterPanel_35_value=&=&queryDialog:j_iduserFilterPanel_38=2008-08-01&queryDialog:j_iduserFilterPanel_41=2008-08-28&queryDialog:filterGrid_modifiedData=[]&queryDialog:filterGrid_removedData=[]&queryDialog:_postback=&queryDialog:userFilterPanel=/cp/bc/dailyLoanBillCommQuery.xhtml&javax.faces.ViewState={vs2}”,
LAST);
通过我的观察,发现有两种情况下的POST请求会被LoadRunner录制为web_custom_request,
1. 上文提到的批量提交多条同属性名称的数据的请求
2. header属性x-requested-by值为XMLHttpRequest的POST请求
这两种实现请求的方法还有一个需要注意的地方就是web_custom_request中body中的属性值如果包含一些特殊字符,必须通过URL编码,否则Web服务器会返回500错误,一个典型的例子是如果Body中包含ViewState,ViewState中常常有“=”之类的特殊字符,此时必须通过URL编码,LoadRuner中提供了一个这样的编码转换函数
web_convert_param(“vs1″, “SourceEncoding=HTML”, “TargetEncoding=URL”, LAST);
除LoadRunner外,你可以在Fiddler中按Ctrl+E来转换。