如何利用gatling创建一个性能测试例
2016-01-10 13:03
429 查看
【原创博文,转载请声明出处】
基于上一篇博文介绍如何源码编译创建自己的gatling可执行工具,今天介绍一下如何基于gatling做性能测试!
由于gatling的测试例脚本是基于scala写的,所以,测试的case脚本当然是一个scala文件了。gatling的测试脚本是用scala写的遵循DSL模型的可读性和维护性极强的脚本。由于DSL重在声明做什么,而不像一般的命令式的编程语言写一堆指令表述怎么做,所以DSL的声明式编程更加侧重在做什么上下功夫,给人一种类似自然语言的程序,但是它比自然语言严格,且准确。当然了,这中DSL声明式编程风格,是基于解释器来完成这些声明背后所承载的具体的程序指令代码,也就是从做什么到怎么做的转换。最终要生成java的字节码程序,交给JVM进行执行,完成要做的事情。
好了,下面,我就进入主题,简单的用一个例子介绍gatling的测试脚本的书写以及测试过程。
直接上测试脚本的代码:(是测试链接baidu主页以及在通过baidu查询cnblogs字符的行为,各重复5,每次执行完毕后暂停10秒)
基于gatling的测试脚本,其实就是一个scala的类,在里面描述做什么事情,并且指定具体的流程,也就是gatling定义的scenario。这个脚本,可以在Scala-eclipse IDE里面写,也可以直接vim文本编写,我这里是在scala-eclipse里面写的。在project里面创建了一个cnblogsCase的package。
这个脚本要放在gatling工具的指定目录下(user-files/simulations),便于执行。因为我的case文件有所属的package,所以,在simulations下面要创建一个目录cnblogsCase。
接下来,执行gatling.sh脚本,进行测试:
截取部分执行过程中的信息:
最终执行完毕后,你会看到如下的结果日志:
在这个测试过程中,你会看到HTTPrequest和HTTP response的message,例如在做search cnblogs的时候,就有下面的这种信息可以看到:
上面的请求和应答中,可以清楚的看到测试的内容和结果。在Http Request的请求行中,可以看到URI的内容,在Http Response的响应行中,可以看到状态信息,都是符合预期的。
这里,罗嗦一下,如何知道脚本中执行search的时候,search的key填写什么?也就是如何构建Http Request的请求行中的URI?其实,这个是要依据自己要测试的目标的网页具体内容的,比如这里要在baidu的主页搜索栏里面查找cnblogs,就要知道URI中的key,再将其的value填写为cnblogs就可以了。这个可以debug模式查看baidu主页的html,还可以很清楚的知道执行指令是用get还是post。
上图中,红色框中,form中没有指定method,则用GET指令(通常如此),在对应的input标签里面的name属性,其值为wd,这个就是要用来构建脚本中的queryParam的key的。是不是比较简单呢?我觉得不是难事!
配置和写脚本都不是什么难事情,现在就要分析一下,脚本测试执行的过程是不是我没预期想要的。主要看看,分析一下执行的次数。我脚本中,设置了5个用户,scenario包含2部分,一个打开主页,一个查询cnblogs字符串,都是执行5次,这么算下来,request一共应该是多少此呢?算算就知道了: 5*(5 + 5) = 50,而结果是不是这样子呢????
请回去查看结果日志,其中的红色部分,就是最终的执行次数,只有20次,说明不服和预期!对于这个结果,我分析了下,没有弄明白,开始以为自己的脚本写的有问题,后来下载了官网版本2.1.7,执行上面的脚本,得到如下的结果:
这个是符合预期的.
为了验证自己的2.2.0-SNAPSHOT从源码编译的结果是不是有问题,自己特意从官网的snapshot中下载了官方的可执行bundle文件.最终执行的结果和我自己编译出来的gatling运行得到的结果一样,这个应该不是我的编译出了问题!
至于2.2.0-SNAPSHOT版本的结果为何不对,目前还没有找到原因,是什么地方出问题了,不会是2.2.0-SNAPSHOT目前还在开发中,存在某些问题吧???有待继续调查!!!还是先不要用最新版本了,继续用2.1.7吧!
最后上传几张截图(基于2.1.7得到的)展示结果:
这个gatling工具,其实还是非常不错的,使用相对比较简单,结果展示也非常友好!相比nGrinder的纯的web UI下的操作,对于初学者可能有比较大的难度,但是,熟悉scala和DSL后,会发现gatling具有很多优势,比如脚本书写非常的灵活,声明式的scenaro的会让其他用户读你写的case毫不费劲!
基于上一篇博文介绍如何源码编译创建自己的gatling可执行工具,今天介绍一下如何基于gatling做性能测试!
由于gatling的测试例脚本是基于scala写的,所以,测试的case脚本当然是一个scala文件了。gatling的测试脚本是用scala写的遵循DSL模型的可读性和维护性极强的脚本。由于DSL重在声明做什么,而不像一般的命令式的编程语言写一堆指令表述怎么做,所以DSL的声明式编程更加侧重在做什么上下功夫,给人一种类似自然语言的程序,但是它比自然语言严格,且准确。当然了,这中DSL声明式编程风格,是基于解释器来完成这些声明背后所承载的具体的程序指令代码,也就是从做什么到怎么做的转换。最终要生成java的字节码程序,交给JVM进行执行,完成要做的事情。
好了,下面,我就进入主题,简单的用一个例子介绍gatling的测试脚本的书写以及测试过程。
直接上测试脚本的代码:(是测试链接baidu主页以及在通过baidu查询cnblogs字符的行为,各重复5,每次执行完毕后暂停10秒)
package cnblogsCase import io.gatling.core.Predef._ import io.gatling.http.Predef._ import scala.concurrent.duration._ class RepeatBaiduSimulation extends Simulation{ val httpConf = http.baseURL("https://www.baidu.com") val homepage = repeat(5){ exec(http("Home page").get("/").check(status.is(200))) .pause(10 seconds) } val searchcb = repeat(5){ exec(http("Search cnblogs").get("/s").queryParam("wd", "cnblogs").check(status.is(200))) .pause(10 seconds) } val scn = scenario("Search baidu home page").exec(homepage, searchcb) //setUp(scn.inject(rampUsers(10) over (60 seconds)).protocols(httpConf)) setUp(scn.inject(atOnceUsers(5)).protocols(httpConf)) }
基于gatling的测试脚本,其实就是一个scala的类,在里面描述做什么事情,并且指定具体的流程,也就是gatling定义的scenario。这个脚本,可以在Scala-eclipse IDE里面写,也可以直接vim文本编写,我这里是在scala-eclipse里面写的。在project里面创建了一个cnblogsCase的package。
这个脚本要放在gatling工具的指定目录下(user-files/simulations),便于执行。因为我的case文件有所属的package,所以,在simulations下面要创建一个目录cnblogsCase。
[root@CloudGame simulations]# pwd /root/.ivy2/local/io.gatling.highcharts/gatling-charts-highcharts-bundle/2.2.0-SNAPSHOT/zips/gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT/user-files/simulations [root@CloudGame simulations]# ll total 8 drwxr-xr-x 2 root root 4096 Jan 10 10:50 cnblogsCase drwxr-xr-x 3 root root 4096 Jan 8 16:02 computerdatabase |
[root@CloudGame gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT]# cd bin/ [root@CloudGame bin]# ll total 132 -rwxr--r-- 1 root root 2898 Jan 8 16:02 gatling.bat -rwxr--r-- 1 root root 1946 Jan 8 16:02 gatling.sh -rwxr--r-- 1 root root 1992 Jan 8 16:02 recorder.bat -rwxr--r-- 1 root root 1134 Jan 8 16:02 recorder.sh -rw-r--r-- 1 root root 118708 Jan 10 11:24 res.txt [root@CloudGame bin]# ./gatling.sh
截取部分执行过程中的信息:
。。。。。。。 11:22:21.552 [main] DEBUG io.gatling.compiler.ZincCompiler$ - } 11:22:21.982 [main] DEBUG io.gatling.compiler.ZincCompiler$ - Initial source changes: removed:Set() added: Set() modified: Set() Invalidated products: Set() External API changes: API Changes: Set() Modified binary dependencies: Set() Initial directly invalidated sources: Set() Sources indirectly invalidated by: product: Set() binary dep: Set() external source: Set() 11:22:21.983 [main] DEBUG io.gatling.compiler.ZincCompiler$ - All initially invalidated sources: Set() 11:22:21.993 [main] DEBUG io.gatling.compiler.ZincCompiler$ - Compilation successful Choose a simulation number: [0] cnblogsCase.RepeatBaiduSimulation [1] computerdatabase.BasicSimulation [2] computerdatabase.advanced.AdvancedSimulationStep01 [3] computerdatabase.advanced.AdvancedSimulationStep02 [4] computerdatabase.advanced.AdvancedSimulationStep03 [5] computerdatabase.advanced.AdvancedSimulationStep04 [6] computerdatabase.advanced.AdvancedSimulationStep05 Select simulation id (default is 'repeatbaidusimulation'). Accepted characters are a-z, A-Z, 0-9, - and _ Select run description (optional) 11:23:00.883 [GatlingSystem-akka.actor.default-dispatcher-4] INFO i.g.c.stats.writer.ConsoleDataWriter - Initializing 11:23:00.887 [GatlingSystem-akka.actor.default-dispatcher-3] INFO i.g.c.stats.writer.LogFileDataWriter - Initializing 11:23:00.897 [GatlingSystem-akka.actor.default-dispatcher-4] INFO i.g.c.stats.writer.ConsoleDataWriter - Initialized 11:23:00.905 [GatlingSystem-akka.actor.default-dispatcher-3] INFO i.g.c.stats.writer.LogFileDataWriter - Initialized 11:23:00.937 [main] DEBUG i.n.u.i.l.InternalLoggerFactory - Using SLF4J as the default logging framework 。。。。。。
最终执行完毕后,你会看到如下的结果日志:
Parsing log file(s) done Generating reports... ================================================================================ ---- Global Information -------------------------------------------------------- > request count 20 (OK=20 KO=0 ) > min response time 8 (OK=8 KO=- ) > max response time 454 (OK=454 KO=- ) > mean response time 123 (OK=123 KO=- ) > std deviation 146 (OK=146 KO=- ) > response time 50th percentile 85 (OK=85 KO=- ) > response time 75th percentile 147 (OK=147 KO=- ) > mean requests/sec 0.198 (OK=0.198 KO=- ) ---- Response Time Distribution ------------------------------------------------ > t < 800 ms 20 (100%) > 800 ms < t < 1200 ms 0 ( 0%) > t > 1200 ms 0 ( 0%) > failed 0 ( 0%) ================================================================================ Reports generated in 0s. Please open the following file: /root/.ivy2/local/io.gatling.highcharts/gatling-charts-highcharts-bundle/2.2.0-SNAPSHOT/zips/gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT/results/repeatbaidusimulation-1452396180846/index.html
在这个测试过程中,你会看到HTTPrequest和HTTP response的message,例如在做search cnblogs的时候,就有下面的这种信息可以看到:
Request DefaultFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: UnpooledHeapByteBuf(freed)) GET /s?wd=cnblogs HTTP/1.1 Referer: https://www.baidu.com/ Cookie: BIDUPSID=FDE533EC959AF63BFE9EFBDFF9822C3E; BAIDUID=FDE533EC959AF63BFE9EFBDFF9822C3E:FG=1; PSTM=1452396098; __bsi=14078739286212139513_00_0_I_R_82_0303_C02F_N_I_I_0; BD_NOT_HTTPS=1; BDSVRTM=0 Connection: keep-alive Host: www.baidu.com Accept: */* Response DefaultHttpResponse(decodeResult: success, version: HTTP/1.1) HTTP/1.1 200 OK Server: bfe/1.0.8.13 Date: Sun, 10 Jan 2016 03:22:29 GMT Content-Type: text/html Content-Length: 227 Connection: keep-alive Last-Modified: Thu, 09 Oct 2014 10:47:57 GMT X-UA-Compatible: IE=Edge,chrome=1 Set-Cookie: BD_NOT_HTTPS=1; path=/; Max-Age=300 Set-Cookie: BDSVRTM=3; path=/ Pragma: no-cache Cache-control: no-cache BDPAGETYPE: 3 BDQID: 0xae1b13fb000760db Accept-Ranges: bytes Set-Cookie: __bsi=14180245014310892240_00_0_I_R_90_0303_C02F_N_I_I_0; expires=Sun, 10-Jan-16 03:22:34 GMT; domain=www.baidu.com; path=/
上面的请求和应答中,可以清楚的看到测试的内容和结果。在Http Request的请求行中,可以看到URI的内容,在Http Response的响应行中,可以看到状态信息,都是符合预期的。
这里,罗嗦一下,如何知道脚本中执行search的时候,search的key填写什么?也就是如何构建Http Request的请求行中的URI?其实,这个是要依据自己要测试的目标的网页具体内容的,比如这里要在baidu的主页搜索栏里面查找cnblogs,就要知道URI中的key,再将其的value填写为cnblogs就可以了。这个可以debug模式查看baidu主页的html,还可以很清楚的知道执行指令是用get还是post。
上图中,红色框中,form中没有指定method,则用GET指令(通常如此),在对应的input标签里面的name属性,其值为wd,这个就是要用来构建脚本中的queryParam的key的。是不是比较简单呢?我觉得不是难事!
配置和写脚本都不是什么难事情,现在就要分析一下,脚本测试执行的过程是不是我没预期想要的。主要看看,分析一下执行的次数。我脚本中,设置了5个用户,scenario包含2部分,一个打开主页,一个查询cnblogs字符串,都是执行5次,这么算下来,request一共应该是多少此呢?算算就知道了: 5*(5 + 5) = 50,而结果是不是这样子呢????
请回去查看结果日志,其中的红色部分,就是最终的执行次数,只有20次,说明不服和预期!对于这个结果,我分析了下,没有弄明白,开始以为自己的脚本写的有问题,后来下载了官网版本2.1.7,执行上面的脚本,得到如下的结果:
Simulation finished Parsing log file(s)... Parsing log file(s) done Generating reports... ================================================================================ ---- Global Information -------------------------------------------------------- > request count 50 (OK=50 KO=0 ) > min response time 7 (OK=7 KO=- ) > max response time 177 (OK=177 KO=- ) > mean response time 63 (OK=63 KO=- ) > std deviation 45 (OK=45 KO=- ) > response time 50th percentile 74 (OK=74 KO=- ) > response time 75th percentile 91 (OK=91 KO=- ) > mean requests/sec 0.494 (OK=0.494 KO=- ) ---- Response Time Distribution ------------------------------------------------ > t < 800 ms 50 (100%) > 800 ms < t < 1200 ms 0 ( 0%) > t > 1200 ms 0 ( 0%) > failed 0 ( 0%) ================================================================================ Reports generated in 0s. Please open the following file: /mnt/workwps/gatling-charts-highcharts-bundle-2.1.7/results/repeatbaidusimulation-1452401293142/index.html
这个是符合预期的.
为了验证自己的2.2.0-SNAPSHOT从源码编译的结果是不是有问题,自己特意从官网的snapshot中下载了官方的可执行bundle文件.最终执行的结果和我自己编译出来的gatling运行得到的结果一样,这个应该不是我的编译出了问题!
至于2.2.0-SNAPSHOT版本的结果为何不对,目前还没有找到原因,是什么地方出问题了,不会是2.2.0-SNAPSHOT目前还在开发中,存在某些问题吧???有待继续调查!!!还是先不要用最新版本了,继续用2.1.7吧!
最后上传几张截图(基于2.1.7得到的)展示结果:
这个gatling工具,其实还是非常不错的,使用相对比较简单,结果展示也非常友好!相比nGrinder的纯的web UI下的操作,对于初学者可能有比较大的难度,但是,熟悉scala和DSL后,会发现gatling具有很多优势,比如脚本书写非常的灵活,声明式的scenaro的会让其他用户读你写的case毫不费劲!
相关文章推荐
- 还是搜索、索引的问题
- 高考之外
- POI操作Excel表格系列5 --- 遇到的问题
- Swift 2.构造函数-子类构造
- C++与C的保留小数
- Effective C++(条款26-31)
- UIButton
- [置顶] Android性能优化笔记
- 汇编复习————指令集
- CPU寄存器操作方式
- jsp中使用out和response.getOutputStream的方法
- 电脑爱好者GHOSTXPSP3网吧专用版V1.0
- Swift之小项目实战
- Android-ListView卡顿优化
- MapReduce算法设计-计算单词共现矩阵
- 荐书一本-----《天才在左,疯子在右》
- [ExtJS5学习笔记]第十五节 Extjs5表格显示不友好?panel的frame属性在作怪
- 如何将自定义标签封装成一个Jar包
- Ubuntu下使用Vi是方向键变乱码 退格键不能使用的解决方法
- QT 编写xml文件实例