关于EXTRARES的扩展说明—性能测试进阶指南 LoadRunner 11实战(第二版)

发表于:2015-1-07 11:01

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:陈霁、李锋、王臣钧    来源:51Testing软件测试网采编原创

(51Testing软件测试网获得作者授权连载本书部分章节。任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责任。)
  (1)首先我们需要将这个代码修改为web_custom_request。
web_custom_request("newforum",
"URL=/phpwind85/admin.php?adminjob=setforum&adminitem=setforum&c_type=&action=addforum&verify=4b39899f",
"Method=POST",
"TargetFrame=",
"Resource=0",
"Referer=",
"Mode=HTML",
"Body=step=2&fup=43&vieworder%5B%5D=&name%5B%5D=a&forumadmin%5B%5D=&style%5B%5D=0&keywords%5B%5D=&descrip%5B%5D=&logo%5B%5D=&vieworder%5B%5D=&name%5B%5D=b&forumadmin%5B%5D=&style%5B%5D=0&keywords%5B%5D=&descrip%5B%5D=&logo%5B%5D=&vieworder%5B%5D=&name%5B%5D=c&forumadmin%5B%5D=&style%5B%5D=0&keywords%5B%5D=&descrip%5B%5D=&logo%5B%5D=&vieworder%5B%5D=&name%5B%5D=d&forumadmin%5B%5D=&style%5B%5D=0&keywords%5B%5D=&descrip%5B%5D=&logo%5B%5D=&vieworder%5B%5D=&name%5B%5D=e&forumadmin%5B%5D=&style%5B%5D=0&keywords%5B%5D=&descrip%5B%5D=&logo%5B%5D=&vieworder%5B%5D=&name%5B%5D=x&forumadmin%5B%5D=&style%5B%5D=0&keywords%5B%5D=&descrip%5B%5D=&logo%5B%5D=&vieworder%5B%5D=&name%5B%5D=&forumadmin%5B%5D=&style%5B%5D=0&keywords%5B%5D=&descrip%5B%5D=&logo%5B%5D=",
LAST);
  (2)动态化Body部分,这里会涉及很多C语言编程和LR参数应用的部分。
char bodystring[1000];
char formstring[1000];
char temp[1000];
int i;
strcpy(bodystring,"step=2&fup=43");//确保43这个forumid是存在的
for (i=1;i<5;i++) {//通过循环可以控制生成的板块个数,动态拼接
sprintf(formstring,"vieworder[]=&name[]=%d&forumadmin[]=&style[]=0&keywords[]=&descript[]=&logo[]=",i);
strcat(temp,"\&");
strcat(temp,formstring);
}
strcat(bodystring,temp);
lr_output_message(bodystring);
lr_save_string(bodystring,"bodyparam");
web_custom_request("newforum",
"URL=http://localhost:8000/phpwind85/admin.php?adminjob=setforum&adminitem=setforum&c_type=&action=addforum&verify=4b39899f",
"Method=POST",
"TargetFrame=",
"Resource=0",
"Referer=",
"Mode=HTML",
"Body={bodyparam}",
LAST);
  通过循环和动态拼接字符串的方式重新构建了一个bodystring的变量,再通过函数转换为参数,最终完成Body数据段的动态重构建。最终的代码如下:
Action()
{
char bodystring[1000];
char formstring[1000];
char temp[1000];
int i;
web_url("phpwind85",
"URL=http://localhost:8000/phpwind85/",
"TargetFrame=",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTML",
LAST);
web_submit_data("login.php",
"Action=http://localhost:8000/phpwind85/login.php",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http://localhost:8000/phpwind85/",
"Snapshot=t8.inf",
"Mode=HTML",
ITEMDATA,
"Name=jumpurl", "Value=http://localhost:8000/phpwind85/index.php", ENDITEM,
"Name=step", "Value=2", ENDITEM,
"Name=pwuser", "Value=admin", ENDITEM,
"Name=pwpwd", "Value=admin", ENDITEM,
"Name=head_login", "Value=", ENDITEM,
"Name=lgt", "Value=0", ENDITEM,
LAST);
web_url("后台配置",
"URL=http://localhost:8000/phpwind85/admin.php",
"TargetFrame=_blank",
"Resource=0",
"RecContentType=text/html",
"Referer=http://localhost:8000/phpwind85/",
"Snapshot=t2.inf",
"Mode=HTML",
LAST);
web_submit_data("admin.php_2",
"Action=http://localhost:8000/phpwind85/admin.php",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http://localhost:8000/phpwind85/admin.php",
"Snapshot=t2.inf",
"Mode=HTML",
ITEMDATA,
"Name=Login_f", "Value=1", ENDITEM,
"Name=verify", "Value=706ee488", ENDITEM,
"Name=admin_name", "Value=admin", ENDITEM,
"Name=admin_pwd", "Value=admin", ENDITEM,
"Name=submit.x", "Value=0", ENDITEM,
"Name=submit.y", "Value=0", ENDITEM,
LAST);
web_url("admin.php",
"URL=http://localhost:8000/phpwind85/admin.php?adminjob=setforum",
"TargetFrame=",
"Resource=0",
"RecContentType=text/html",
"Referer=http://localhost:8000/phpwind85/admin.php",
"Snapshot=t3.inf",
"Mode=HTML",
LAST);
strcpy(bodystring,"step=2&fup=43&");//确保43这个forumid是存在的
for (i=1;i<5;i++) {
sprintf(formstring,"vieworder[]=&name[]=%d&forumadmin[]=&style[]=0&keywords[]=&descrip[]=&logo[]=",i);
strcat(temp,"\&");
strcat(temp,formstring);
}
strcat(bodystring,temp);
lr_output_message(bodystring);
lr_save_string(bodystring,"bodyparam");
web_custom_request("newforum",
"URL=http://localhost:8000/phpwind85/admin.php?adminjob=setforum&adminitem=setforum&c_type=&action=addforum&verify=4b39899f",
"Method=POST",
"TargetFrame=",
"Resource=0",
"Referer=",
"Mode=HTML",
"Body={bodyparam}",
LAST);
return 0;
}
  在实际应用中该代码还不能真正有效地运行起来,因为phpwind对于操作还附加了verify关键字来做动态session操作验证,所以还需要使用关联技术将这个内容进行一下处理,大家在了解后面的关联概念后可以自行尝试将这个代码中的动态数据规范处理。
  所以说web_custom_request()函数是一个非常强大的请求模拟函数,它不但可以模拟HTTP协议中的Get请求,还能模拟POST请求,在模拟通过HTTP协议发送自定义数据包时经常会使用到它。
  2)高级选项下的Non HTML-generated elements(e.g. JavaScript,VBScript,ActiveX, Applets)选项
  这个选项是对非标准的HTML元素的处理方式,VuGen有以下3种处理方式。
  Record within the current script step:对于JavaScript等内容直接作为web_url下的附属信息记录。
  Record in separate steps and use concurrent groups:对于相关的内容新建一个web_url来处理。
  Do not record:不录制额外的内容。
  在默认情况下选择直接录制在web_url下,如果某些内容录制会导致脚本回放错误,那么可以不录制该内容。
  URL-based Script:是基于URL请求的脚本录制方式,会录制得到所有的HTTP请求。选择该选项会录制所有的HTTP请求,导致脚本包含大量的web_url()函数,参考前面HttpWatch获得的HTTP交互过程,VuGen只是将所有的请求抓取出来,并且对每个请求均生成一个web_url()函数来进行模拟。
  使用URL-based Script录制出来的代码都会附带一个Mode=HTTP的字段,说明该请求是使用HTTP模式来回放的,而不是前面的HTML模式。HTTP模式是指对该请求只做返回保存,而HTML模式是指返回的内容系统会尝试使用HTML解释器进行运行(如果我们只需要对服务器做核心处理,性能测试可以放弃页面处理部分,修改MODE=HTTP把负载着重放在业务上),然后完成HTML中的载入CSS、图片、JS脚本请求。
  web_url("phpwind85",
  "URL=http://localhost:8000/phpwind85/",
  "Resource=0",
  "RecContentType=text/html",
  "Referer=",
  "Snapshot=t1.inf",
  "Mode=HTTP",
  LAST);
  web_concurrent_start(NULL);
  web_url("pw_core.css",
  "URL=http://localhost:8000/phpwind85/images/pw_core.css?101128",
  "Resource=1",
  "RecContentType=text/css",
  "Referer=http://localhost:8000/phpwind85/",
  "Snapshot=t2.inf",
  LAST);
  //部分代码略
  web_concurrent_end(NULL);
  这里会有两个新函数web_concurrent_start(NULL)和web_concurrent_end(NULL),这两个函数可以帮助我们生成并发请求。当我们刷新一个页面时,HTML首先会被独立返回,然后解释HTML的过程中,浏览器会并行下载资源从而提高性能,但是LR录制所产生的并发操作并不是非常精确,实际情况浏览器并不能使用那么多的并行操作。
  在绝大多数情况下我们一般都是使用HTML-Base Script模式来录制的,所以访问一个页面的请求对应的资源下载都是自动实现的,如果需要对某请求实现并发,真实的情况是多个用户并发访问一个请求,而不是多个不同的请求并发给服务器。实现并发的策略应该使用集合点函数而不是使用web_concurrent_start和web_concurrent_end函数,因为这两个函数不能实现虚拟用户与虚拟用户之间的并发行为。
  思考:
  什么时候应该用HTML-based script?什么时候应选择URL-based script?
  一般来说如果是标准使用IE访问的B/S架构,应该使用HTML-base script下的A script containing explicit URLs only方式来录制脚本,这种脚本基于URL请求完成,不会带有任何前后依赖的内容。而如果是一个非HTML标准的C/S架构,建议使用URL-base script来录制脚本,这样可以确保不会遗漏任何HTTP请求。
  例如:如果使用HTTP进行数据传送,而数据内容是存放在.dat文件中的,那么使用HTML-base script就无法录制到对该.dat文件的操作,而使用URL-base script就可以录制出来。
  ② Network
  不是所有的对象都能够被LR启动录制的,例如,基于特殊浏览器、手机终端或者Linux下的应用,我们无法通过VuGen启动被录制对象,那么这个时候通过Port Mapping的代理模式就可以将它们录制下来。
  Port Mapping提供了对于端口映射的处理规则,通过其内置的代理服务器,可以将通过代理服务器的协议内容录制下来,其实现原理如图A.20所示。
  
图A.20  Port Mapping实现原理
本文选自《性能测试进阶指南—LoadRunner 11实战(第二版)》,本站经作者的授权。
版权声明:51Testing软件测试网获作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责任。
53/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号