性能测试-Loadrunner、Jmeter 性能测试概念详解+性能方案+代码录制(待完善)
其他
2019-06-16 11:21:30
阅读次数: 0
Loadrunner和Jmeter:
- Loadrunner,社区版本,一台机器最多能开50个并发。四台机器就是200个,四台机器分别手动设置LR运行参数,执行完后分别统计运行结果再汇总到一起。收费版本收费非常贵,按照不同协议,并发数来收费。
- Jmeter,开源,支持编程,但是不然Loadrunner支持的彻底。是轻量的,百八十兆,在mac下装java环境就可以做性能测试。
性能测试:
- 性能测试:在不同负载情况下,查看被测试系统的表现。
- 前端性能:app性能(GT、Emmagee)。
- 后端性能:接口和服务。
性能指标:
- TPS 和平局响应时间:并发多少?多快?正确?这三种情况下占用了多少资源。
性能测试的全流程:
- 1
性能测试的最大原则:
- 模拟最可能发生的最极端并发访问的情况。
Loadrunner工具三个部分:
- virtualuser generator:虚拟用户生成器:录制脚本、调试脚本、单线运行。
- controller:设定性能测试场景,来运行多线程(多进程)并发,执行并发测试。
- analysys:分析性能测试执行后的结果,可以出图表报告。
- 补充:ipspoofer:ip欺骗,把所有内网IP做遍历,一般内网是有几百个IP,LR跑的话一般一分钟左右就跑完了,没啥意义,所以为了测试大量IP,需要开发把限制IP关掉再做测试性能。但是这种情况就和真实情况不相符了,要综合考虑。
概念详解:
- 开始-HP Software-Start HP Web tours Server,相当于启动服务,然后打开http://127.0.0.1:1080/WebTours/index.htm 工具自带的网站,打开网页点击administration,在做关联的时候需要选择第三个Set LOGIN form's action tag to an error page.
- 关联:把动态的数据放到变量中,会在后续的测试中使用。比如登录了之后,系统返回一个token(串),访问所有后续的页面会带有这个token。录制的脚本拿到token,但是都是之前历史值,在性能测试时并不能复用,所以需要做关联。
- 参数化:避免大量的请求被缓存命中。
创建录制脚本:
- 启动virtualuser generator,File-new Script and solution-WebHttpHtml,创建在了C:\Users\太阳\Documents\VuGen\Scripts路径下的录制脚本文件。
- 脚本的结构:
- vuser_init:函数,
在一个线程中最多执行1次
一个用于数据准备等操作,在action前执行
- action:函数,在一个线程中可以执行1-多次
- vuser_end:函数在一个线程中最多执行1次
一个用于数据清理等操作
在action后执行。
- 点击录制图标录制,选择浏览器、录制模式、录制网址
- 在网页中执行注册的操作,同时LR就开始自动录制了,注册结束后点击结束按钮,LR生成录制的脚本,打开action后就可以看到:对应其他收集用户信息的脚本可以删掉。以下是重点脚本解析,
- web_url("index.htm", //请求的名字
"URL=http://127.0.0.1:1080/WebTours/index.htm", //请求的网址
"Resource=0", //是否是资源,0不是资源是网页,1是资源:文件、图片、js、css
"RecContentType=text/html", //contentType,请求类型是网页类型
"Referer=", //请求这个网页的时候是从哪个网址访问来的信息
"Snapshot=t2.inf", //截图文件名字
"Mode=HTML", //录制模式HTML,还有种模式是URL,如果有ajax、flash等必须使用url。url会把所有的http请求都录下来
EXTRARES, //下面全是资源文件,"Url=http://www.duba.com/hotwords.json", "Referer=", ENDITEM,这些都是静态的资源文件,如果只想测试动态的数据,则可以把下面这行删除,如果动态和静态都想测试则不需要清空
"Url=http://www.duba.com/hotwords.json", "Referer=", ENDITEM,
LAST);
- web_submit_data("login.pl_2",
"Action=http://127.0.0.1:1080/cgi-bin/login.pl", //数据提交后的处理网址
"Method=POST", //HTTP协议的类型
"RecContentType=text/html", //提交的资源类型,contenttype
"Referer=http://127.0.0.1:1080/cgi-bin/login.pl?username=&password=&getInfo=true", //从哪个网址跳转过来的
"Snapshot=t12.inf",
"Mode=HTML",
ITEMDATA, //这个下面的这些也可以手动写入,通过抓包获得相关信息
"Name=username", "Value=changjinling", ENDITEM,
"Name=password", "Value={PasswordParameter}", ENDITEM,
"Name=passwordConfirm", "Value=123456", ENDITEM,
"Name=firstName", "Value=chang", ENDITEM,
"Name=lastName", "Value=jinling", ENDITEM,
"Name=address1", "Value=beijing", ENDITEM,
"Name=address2", "Value=tongzhou", ENDITEM,
"Name=register.x", "Value=60", ENDITEM, //UI页面上没看到的字段,是隐含字段,基于安全考虑,比如多长时间之内提交是有效的。
"Name=register.y", "Value=9", ENDITEM, //是隐含字段
LAST);
- 注册全部脚本:Action()
{
web_add_auto_header("DNT",
"1");
web_url("index.htm", //请求的名字
"URL=http://127.0.0.1:1080/WebTours/index.htm", //请求的网址
"Resource=0", //是否是资源?0,不是资源,是个网页,1:是资源:文件:图片、js、css..
"RecContentType=text/html", //contentType:请求类型:网页类型
"Referer=", //从哪个网址访问来的信息
"Snapshot=t1.inf", //截图文件的名字
"Mode=HTML", //录制的模式:html, url。如果有ajax\flash\:必须使用url:会把所有的http请求录制下来。
EXTRARES, //资源文件
"Url=../favicon.ico", "Referer=", ENDITEM,
"Url=http://s.pc.qq.com/navigate/adc/adc_loader.js?v=20160326171611", ENDITEM,
"Url=http://s.pc.qq.com/navigate/adc/v4/engine_loader_v3.js", ENDITEM,
"Url=http://s.pc.qq.com/navigate/adc/jquery.min.js?ver=3", ENDITEM,
"Url=http://s.pc.qq.com/navigate/adc/velocity.js", ENDITEM,
LAST);
web_set_sockets_option("SSL_VERSION", "2&3");
web_url("login.pl",
"URL=http://127.0.0.1:1080/WebTours/login.pl?username=&password=&getInfo=true",
"Resource=0",
"RecContentType=text/html",
"Referer=http://127.0.0.1:1080/WebTours/home.html",
"Snapshot=t3.inf",
"Mode=HTML",
LAST);
web_add_cookie("SRCHD=AF=NOFORM; DOMAIN=iecvlist.microsoft.com");
web_add_cookie("SRCHUID=V=2&GUID=213C7604B2E646778D68C0E2C5F9563A&dmnchg=1; DOMAIN=iecvlist.microsoft.com");
web_add_cookie("SRCHUSR=DOB=20190119; DOMAIN=iecvlist.microsoft.com");
web_add_cookie("MC1=GUID=1cc40e7eeb084d58a1a4aab5a0176a31&HASH=1cc4&LV=201903&V=4&LU=1553846123710; DOMAIN=iecvlist.microsoft.com");
web_add_cookie("MUID=30550888172C666B26C505A6132C607F; DOMAIN=iecvlist.microsoft.com");
web_add_auto_header("UA-CPU",
"AMD64");
web_revert_auto_header("UA-CPU");
web_submit_data("login.pl_2",
"Action=http://127.0.0.1:1080/WebTours/login.pl", //数据提交后的处理网址
"Method=POST", //http协议的类型
"RecContentType=text/html", //资源类型,contenttype
"Referer=http://127.0.0.1:1080/WebTours/login.pl?username=&password=&getInfo=true",
"Snapshot=t6.inf",
"Mode=HTML",
ITEMDATA,
"Name=username", "Value=tianchuan", ENDITEM,
"Name=password", "Value=tianchuan", ENDITEM,
"Name=passwordConfirm", "Value=tianchuan", ENDITEM,
"Name=firstName", "Value=tianchuan", ENDITEM,
"Name=lastName", "Value=tianchuan", ENDITEM,
"Name=address1", "Value=tianchuan", ENDITEM,
"Name=address2", "Value=tianchuan", ENDITEM,
"Name=register.x", "Value=57", ENDITEM,
"Name=register.y", "Value=13", ENDITEM,
LAST);
return 0;
}
- 通过脚本回放的话,一个用户名密码重复注册是不会成功的,虽然http返回了200,但是实际上注册是没有成功的,即业务上是没有成功的。在web_submit_data("login.pl_2", 前要加一行断言代码,如果注册成功了则不保存,否则报错 //断言放到请求的前面,如果成功了则页面会有Thank you这样的字样
web_reg_find("text=Thank you,",LAST)。如果注册成功则在执行log中可以看到提示:Action.c(220): Registered web_reg_find successful for "Text=Thank you," (count=1) [MsgId: MMSG-26364]。如果注册失败则在执行log中可以看到提示:Action.c(220): Error -26366: "Text=Thank you," not found for web_reg_find [MsgId: MERR-26366]。
- 参数化,用户名可以用随机数做,也可以用文件,将数字部分做随机数,右击2,参考如图
- 想看到脚本执行的参数是多少,可以设置以下,再执行,就可以在log中看到参数的实际的值了。 Action.c(220): Notify: Parameter Substitution: parameter "randomnumber" = "76064"
Action.c(220): Notify: Parameter Substitution: parameter "PasswordParameter" = "123456"
- 想看到执行时网页的操作页面,通过设置Tools-options-Scripting-replay-show run-time viewer during replay。
- 通过文件做参数化如图设置,这里要注意以下Select next row的内容的选择,如果选择了Unique,小截图中的参数才能可用可选,具体含义如下:
- 设置action一共跑几次可用通过
- 如果想要分析问题,想得到更多的log,可以在log中选中,然后回放的时候就可以在日志中看到更多的服务返回的信息。
- 录登录的脚本。
- 自动关联,必须有两个页面有相同的内容才能关联,在Design-Design Studio中选中后点击Correlation。这样在脚本中就会自动添加如下代码: /*Correlation comment - Do not change! Original value='126029.393681652zticzDzpQDHfDiiQfpicVzcf' Name ='userSession' Type ='ResponseBased'*/
web_reg_save_param_regexp(
"ParamName=userSession",
"RegExp=name=\"userSession\"\\ value=\"(.*?)\"/>\\\n<table\\ border",
SEARCH_FILTERS,
"Scope=Body",
"IgnoreRedirections=No",
"RequestUrl=*/nav.pl*",
LAST); 这样的话,原脚本就会被自动的将userSession的值变为关联后 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=t33.inf",
"Mode=HTML",
ITEMDATA,
"Name=userSession", "Value={userSession}", ENDITEM,
"Name=username", "Value=changjinling", ENDITEM,
"Name=password", "Value={PasswordParameter}", ENDITEM,
"Name=JSFormSubmit", "Value=off", ENDITEM,
"Name=login.x", "Value=32", ENDITEM,
"Name=login.y", "Value=9", ENDITEM,
LAST);
- 手动关联,假如只有一个页面想要做关联,首先需要在源码中找到需要关联的内容的左右边界,
- Runtime Settings菜单介绍。
- 接口测试的写法 Action()
{
lr_rendezvous("hi");
web_reg_find("Text={\"code\": \"00\", \"userid\": ",
LAST);
web_rest("POST: http://39.106.41.11:8080/register/",
"URL=http://39.106.41.11:8080/register/",
"Method=POST",
//"EncType=raw",
//"Snapshot=t854649.inf",
"Body={\"username\":\"wxh22{usenum}\",\"password\":\"12345678abc\",\"email\":\"[email protected]\"}",
LAST);
return 0;
},目前这个接口只要code返回00就是业务上注册成功了。
- 延伸:注册后需要登录,登录后返回值有token,需要将token取出来存到变量里,在后面的接口请求都可以用这个token作为请求参数去发送请求。
- Controller
- 启动Controller,有手动模式和目标模式两种方式,
- TPS拐点
- 如果想分析结果,最好可以通过对服务器端日志中得到更加具体的数据请求的时间等。
- 接口的响应时间,一百毫秒以上就是比较慢的了,一百毫秒以下就是不错的。
- Analysis
- 图示分析,在Average Transaction Response Time图标中右击选择Show Transaction Breakdown Tree,如图示:
- 网络流程:通过dns-找到ip-建立连接-发送请求-等待服务器处理-接收服务器返回数据-断开连接,first buffer time:等待服务器处理+返回数据的第一个字节在网上的传输时间。
转载自blog.csdn.net/chang_jinling/article/details/89428668