web_custom_request
LR帮助文档的定义
Allows you to create a custom HTTP request with any method supported by HTTP.
Allows you to create a custom HTTP request using any method or body. By default, VuGen generates this function only for requests that could not be interpreted with other web functions.
int web_custom_request( const char *RequestName, <List of Attributes>,[EXTRARES, <List of Resource Attributes>,] LAST );
web_custom_request()函数是一个可以用于自定义http请求的“万能”函数。页面的提交方式,POST、GET、PATCH、PUT等。
数据提交形式:
A、post+JSON格式参数:
1)参数都写在一行: "Body={"arg1":int_value1,"arg2":"str_value2",…, "argN":"valueN"}",
2)参数不都在同一行
"Body={"arg1":value1,"
""arg2":"str_value2","
""arg3":"str_value3","
……
""argN":"valueN"}",
B、post+非JSON格式参数:
“Body=属性名称=属性值&属性名称=属性值&……”
示例:
web_custom_request( …… "BodyUnicode=REPRICE" "BodyBinary=\\x08\\x00\\xCC\\x02\\x00\\x00" "Body=.\r\n" "-dxjjtbw/(.tp?eg:ch/6--\r\n", LAST);
不同的应用中,请求体分别通过Body、BodyBinary或者BodyUnicode参数来传递。请求体可以只使用其中一个参数,也可以使用一连串的分开的参数组成多请求体。
在上面的代码中,使用了3个参数来划分请求体,一个是Unicode,一个是二进制,最后一个是常规的字符串。最终的请求体是这3个参数按照在函数中的顺序连接起来的值。还有一个很少用到的参数,Binary。它也能描述二进制请求体,但只允许函数中只有一个请求体参数。所有的请求体都是ASCII字符,以null结束。
它也可以使用二进制字符串。
char *abc= .../* a pointer to the raw data */ web_custom_request("StepName", "URL=http://some.url ", "Method=POST", RAW_BODY_START, "abc", 3, RAW_BODY_END, LAST);
当使用web_custom_request()函数来发送http的get和post请求时,如果未使用web_add_header相关函数来自定义添加头部,请求中带有默认的http请求头部字段。
web_url("file.html", "URL=http://lazarus/html/forms/file.html", "TargetFrame=_TOP", LAST ); web_add_header("Content–Type","multipart/form–data; boundary=–––––––––––––––––––––––––––292742461228954"); web_custom_request("post_query.exe", "Method=POST", "URL=http://lazarus/cgi–bin/post_query.exe", "Body=–––––––––––––––––––––––––––––292742461228954\r\nContent–Disposition: form–data; name=\"entry\"\r\n\r\nText\r\n–––––––––––––––––––––––––––––292742461228954\r\nContent–Disposition: f–––––––––––292742461228954––\r\n", "TargetFrame=", LAST );
如需要修改默认的头部字段或增加其他头部字段就在web_custom_request()函数的前面使用web_add_header()函数来添加;
如果要减少某个头部字段或全部自动添加的头部字段就在web_custom_request()函数的前面使用web_remove_auto_header()和web_revert_auto_header(),头部字段所有请求中公共的一些头部可以放在web_add_auto_header()函数中,配合web_add_header系列函数来完成自定义的业务脚本。
转自Loadrunner 关联 web_custom_request综合实例 的一个实例。
Loadrunner 关联web_custom_request,针对自带的订票系统的一个综合实例,相信看了本文大家对学习loadrunner脚本会有很大的帮助. 本实例要解决的问题: (1)动态删除Loadrunner订票系统的一条订单; (2)动态判断表单订单条目,执行取消第一条订单; (3)Loadrunner关联 web_custom_request以及循环语句的应用。 代码不足之处:变量定义太多,希望和大家共同交流。 以下为我的脚本的源码: ------------------------------------------------------ #include "web_api.h" Action() { int i,k; char form[1024]; char temp[1024]; char tmp[1024]; char tp[1024]; char tp1[1024]; char tp2[1024]; web_url("MercuryWebTours", "URL=http://192.168.8.9/MercuryWebTours/", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTML", LAST); lr_think_time(10); web_submit_form("login.pl", "Snapshot=t2.inf",ITEMDATA, "Name=username","Value=zhangming", ENDITEM, "Name=password","Value=666666", ENDITEM, "Name=login.x", "Value=50",ENDITEM, "Name=login.y", "Value=11",ENDITEM, LAST); lr_think_time(4); web_reg_save_param("flightID", "LB=INPUT TYPE=\"hidden\" NAME=\"flightID\"VALUE=\"", "RB=\"", "ORD=ALL", "search=body", LAST); web_image("Itinerary Button", "Alt=Itinerary Button", "Snapshot=t3.inf", LAST); strcpy(form,"Body=1=on"); i=atoi(lr_eval_string("{flightID_count}")); for(k=1;k<=i;k++) { sprintf(temp,"{flightID_%d}",k); strcpy(tmp,lr_eval_string(temp));//取出flightID的值,并把值传给tmp sprintf(tp,"&flightID=%s",tmp); strcat(form,tp); } for(k=1;k<=i;k++) { sprintf(tp2,"&.cgifields=%d",k); strcat(tp1,tp2); } strcat(form,tp1); strcat(form,"&removeFlights.x=137&removeFlights.y=13"); lr_output_message("form 的值为=%s",form); web_custom_request("itinerary.pl", "url=http://192.168.8.9/MercuryWebTours/itinerary.pl", "Method=POST", "RecContentType=text/xml", form, "Snapshot=t7.inf", LAST); return 0; }
web_submit_data
LR帮助文档的定义
Performs an "unconditional" or "contextless" form submission. It allows you to generate GET and POST requests as made by the HTML forms. You do not need to have a form context to execute this request.
int web_submit_data( const char *StepName, const char *Action, <List of Attributes>, ITEMDATA, <List of data>, [ EXTRARES, <List of Resource Attributes>,] LAST );
示例:
数据提交形式:“Name=属性名称,”,“Value=属性值”
In the following example, the web_submit_data function submits a form using the POST method:
web_submit_data("default.aspx", "Action=http://lazarus/flightnet/default.aspx", "Method=POST", "TargetFrame=", "RecContentType=text/html", "Referer=http://lazarus/flightnet/", "Snapshot=t7.inf", "Mode=HTML", ITEMDATA, "Name=grpType", "Value=radRoundtrip", ENDITEM, "Name=lstDepartingCity", "Value=DEN", ENDITEM, "Name=lstDestinationCity", "Value=LAX", ENDITEM, "Name=txtDepartureDate", "Value=8/19/2003", ENDITEM, "Name=txtReturnDate", "Value=8/19/2003", ENDITEM, "Name=txtQuantity", "Value=1", ENDITEM, "Name=radClass", "Value=1", ENDITEM, "Name=radSeat", "Value=1", ENDITEM, "Name=btnAvailableFlights", "Value=Next >", ENDITEM, LAST ); In the following example, the web_submit_data function submits two files using the POST method: web_submit_data("Attachments", "Action=http://barton.cottage@.Devonshire.uk/Attachments?YY=45434", "Method=POST", "EncType=multipart/form–data", "TargetFrame=", "RecContentType=text/html", "Referer=http:///barton.cottage@.Devonshire.uk/Compose?YY=20435", "Snapshot=t5.inf", "Mode=HTML", ITEMDATA, "Name=userFile0", "Value=E:\\sense_sensibility\\Elinor.htm", "File=yes", "ContentType=text/html", // Override default "text/plain" for .txt files FilePath=Elinor.txt", "ContentTransferEncoding=html/text", ENDITEM, "Name=userFile1", "Value=E:\\sense_sensibility\\Marianne.jpg", "File=yes", ENDITEM, LAST );
http接口实例
loadrunner接口测试原理是web_submit_data函数发送post或者get请求,将测试用例数据进行参数化,使用关联获取响应的结果值,与预期结果进行比对,将过程中相关的参数保存到html文件中,从而实现接口自动化,实现代码如下: 1、Init部分:生成html格式文件,文件名称为 test _系统时间(%Y%m%d%H%M%S)_虚拟用户编号,并写入测试结果文件的html开始标识 //定义结果文件变量 long file; //定义虚拟用户编号变量 char *vusernum; //定义测试结果变量 char V_Result[1024]; vuser_init() { //取得虚拟用户编号 vusernum=lr_eval_string ("_{vuserid}"); //取得系统时间 lr_save_datetime("%Y%m%d%H%M%S", DATE_NOW, "now_date"); //拼接测试结果文件名称 strcpy(V_Result,"d://test/Result/test"); strcat(V_Result,lr_eval_string("_{now_date}")); strcat(V_Result,vusernum); strcat(V_Result,".html"); //生成并打开测试结果文件 file=fopen(V_Result,"at+"); //写入测试文件头部html信息 strcpy(V_Result,"<html><table border='1'><tr>< td>IMSI号码</td><td>预期值</td><td>返回值< /td><td>结果</td></tr>"); fputs(V_Result,file); return 0; } 2、Action部分:从参数化文件读取测试参数和预期结果、发送请求并获得服务器返回实际结果,比较测试结果后写入测试结果文件。 Action() { //测试结果文本 char V_testres[1024]; //定义返回结果是否正确变量 int result; //取得IMSI号码 char *V_imsi=lr_eval_string ("{IMSI}"); //设置页面接收最大的字节数,该设置应大于服务器返回内容的大小 web_set_max_html_param_len("20000"); //取得服务器返回内容 web_reg_save_param("filecontent", "LB=", "RB=", "Search=Body", LAST); //发送请求 web_submit_data("login", "Action=http://host:port/autonavit/search?cmd=clientlogin&termver=5&termcode=30001&termdbver=3 ", "Method=POST", "RecContentType=text/html", "Referer=", "Snapshot=t9.inf", "Mode=HTTP", ITEMDATA, "Name=imsi", "Value={IMSI}", ENDITEM, LAST); //比较预期值和实际值是否相等 result=strcmp(lr_eval_string("{YQJG}"),lr_eval_string("{filecontent}")); if ( result == 0 ) { strcpy(V_testres,"通过"); } else { strcpy(V_testres,"失败"); } strcpy(V_Result,"<tr><td>"); //写入测试参数 strcat(V_Result,V_imsi); strcat(V_Result,"</td>"); strcat(V_Result,"<td id='yq'>"); //写入预期结果 strcat(V_Result,lr_eval_string("{YQJG}")); strcat(V_Result,"</td>"); strcat(V_Result,"<td id='sj'>"); //写入实际结果 strcat(V_Result,lr_eval_string("{filecontent}")); strcat(V_Result,"</td>"); strcat(V_Result,"<td>"); //写入测试是否通过 strcat(V_Result, V_testres); strcat(V_Result,"</td></tr>"); fputs(V_Result,file); return 0; } 3、End部分:写入测试结果文件尾部html信息,关闭文件并结束测试。 vuser_end() { //结束并关闭文件 strcpy(V_Result,"</table></html>"); fputs(V_Result,file); fclose(file); return 0; }
如何选择录制方式,会生成上述两种函数?
区别:
1、从理论上讲,web_custom_request函数属于万能函数,完全可以替代web_link()、web_url()、web_submit_data()这些函数的存在。 request函数页面的提交方式,POST、GET、PATCH、PUT等,web_submit_data只能提交html页面的get和post请求。
2、header?
3、
使用web_custom_request的方式:
1.批量提交多条同属性名称的数据的请求。这种形式也手动换为request函数(有时需要“&”都替换成%
26
)。
2.header属性x-requested-by值为XMLHttpRequest的POST请求。
比如“查询所有邮件并删除”中,查询时使用关联把所有邮件对应的标识抓取成一个数组,如果使用web_submit_data来完成这个删除的请求,需要很多个web_submit_data请求才能完成,但使用web_custom_request就可以通过一个请求完成,方法是写代码拼一个web_custom_request 方法POST请求的Body值。
手动写web_custom_request时需要注意的问题:
1、特殊字符
web_custom_request中body中的属性值如果包含一些特殊字符,必须通过URL编码,否则Web服务器会返回500错误,一个典型的例子是如果Body中包含ViewState,ViewState中常常有“=”之类的特殊字符,此时必须通过URL编码。
2、EncType编码类型
此参数给出一个内容类型(Content-Type),指定其做为回放脚本时“Content-Type”请求头的值,例如“text/html”。Web_custom_request函数不处理未编码的请求体。请求体参数将会使用已经指定的编码方式。因此,如果指定了不匹配HTTP请求体的“EncType”,会引发服务端的错误。通常我们建议不要手动修改录制时的“EncType”值。
任何对于“EncType”的指定都会覆盖web_add_[auto_]header函数指定的Content-Type。当指定了“EncType=”(空值)时,不会产生“Content-Type” 请求头。当省略了“EncType”时,任何一个web_add_[auto_]header函数都会起作用。如果既没有指定EncType也没有web_add_[auto_]header函且“Method=POST”,“application/x-www-form-urlencoded”会做为默认值来使用。其他情况下,不会产生Content-Type请求头。
参考资料: