Gatling
下载是一款开源的性能测试工具,提供简洁、强大的DSL API编写测试套件,支持插件扩展,且自动生成美观、明了的HTML测试报告。
Gatling
现在最新版本是:2.1.7
。需要scala 2.11
支持。
Gatling
有多种执行方式,可以使用官话的bundle
包,使用gatling.sh
脚本执行,也可以使用使用gatling-sbt
下载在Sbt
工程里执行,也可以集成到如Jenkins
这样的持续集成工具里执行。
使用Gatling
在http://gatling.io/#/download
下载Gatling bundle 2.1.7,下载后解压,目录如下:
1 | yangjing-mac-air:gatling-charts-highcharts-bundle-2.1.7 $ tree -d -L 3 |
bin
目录的下放了两种启动脚本,分别有Unix Like
和Windows
环境的脚本 。gatling.sh
是执行测试的脚本,它会列出已有的所有测试文件,并选择执行。而recorder.sh
是一个图形化的Gatling
脚本配置工具,通过很简洁的界面开始编写基础的Gatling
测试脚本。
lib
目录下是Gatling
所依赖的库文件。
用户编写的测试脚本放在user-files/simulations
目录下,Gatling
已经自带了一个测试样例供参考。user-files/data
目录可以放一些测试需要的测试数据,比如用户名和密码等。Gatling
提供了对CSV
文件的良好支持,可以把一组测试用户数据保存在一个CSV
文件里,由Gatling
读取。
最终生成的测试报告将会放在results
目录。
Gatling
自带了几个测试脚本,可以执行./bin/gatling.sh
运行。这可以做为一个很好的开始Gatling
测试的方式。
在sbt
项目中使用Gatling
在平常的测试、开发中,每次都把测试脚本放到 user-files/simulations
目录,并通过gatling.sh
脚本执行,感觉有些不方便。我们可以使用 Gatling sbt-plugin 把Gatling
很方便的集成到sbt
工程里。
示例工程地址:https://github.com/yangbajing/gatling-example。
sbt
工程配置
project/plugins.sbt
添加gatling插件
1 | addSbtPlugin("io.gatling" % "gatling-sbt" % "2.1.7") |
project/Build.scala
添加gatling依赖库
1 | "io.gatling.highcharts" % "gatling-charts-highcharts" % "2.1.7" % "provided,test" |
Gatling
测试脚本的编写
每个gatling测试脚本都需要继承Simulation
抽象类,同时还要导入以下包:
1 | import io.gatling.core.Predef._ |
编写Gatling
测试脚本
一般gatling脚本的编写分为3部分:
- 定义 http protocols:定义能用的http header选项,设置要测网址的baseURL。
- 编写 scenario: 每个剧本定义了一套测试脚本,使用
exec
执行实际的测试动作。 - 设置 scenario并执行:使用
setUp
装载多个scenario
,并设置同时多少个用户并发访问,以及访问方式(在一个时间点内同时并发还是在一段时间内渐进并发)等。
http protocol
1 | http |
baseUrl
用于设置待测试网址的域名,其它设置是为了模拟浏览器的请求头。
scenario
scenario
用于定义一组测试脚本,使用exec
命令来执行一个HTTP Request。多个HTTP Request可以链式调用。
1 | val helloscalaSDKApiScenario = scenario("HelloscalaSDKApi") |
feed
用于导入用户定义数据,可以从文件导入,也可以编程生成。Gatling
默认提供了csv
、tsv
、ssv
、jsonFile
等多种文件导入方法。feed
也支持传入一个Seq[Map[String, T]]
类型的用户生成数据。接下来会用编程方式生成一堆测试用户ID。
.exec
设置要执行的测试请求,输入类型主要有两类:XXXXBuilder
和Expression[Session]
。XXXXBuilder
用于加入测试请求,Expression[Session]
用于设置Gatling
的Session状态。定义的几个测试请求动作代码如下:
1 | // 生成1000个测试externalId |
先来看看resetTimestamp
做了什么工作,
1 | def resetTimestamp = exec(session => session.map(_.set("timestamp", System.currentTimeMillis().toString))) |
因为是对REST
风格的一个API作压力测试,而API接入文档要求每次接入时都需要根据sharedSecret
、http method
、api path
、timestamp
、query string
做一个Hash,再将生成的token存入http header
。
而这段代码的意思就是当前时间戳存到Gatling Session
中,这样在每次exec
调用前都重置下Session中的timestamp
变量,可以更好的模拟真实的API调用环境。
${timestamp}
这样的语法是Gatling
提供的EL,见:http://gatling.io/docs/2.1.7/session/expression_el.html。使用字符串插值的方式可以方便的获取到Gatling Session
里保存的变量,包括用feed
导入的用户数据。
再看userLabels
这个方法,这里有特色的一部分是对sc-api-token
的设置。对于一个基于REST
风格的API,在每次请求时都进行访问校验是一种常用方式,而这个sc-api-token
的计算就由computeToken
函数来完成。computeToken
函数定义如下:
1 | def computeToken(method: String, timestamp: SessionAttribute, apiPath: String, queryString: String = "") = { |
但是在这里,我们不能直接把"${timestamp}"
和"externalId=${externalId}"
当作字符串参数传给computeToken
函数,因为computeToken
函数的执行并不在Gatling Session
的执行上下文中。我们必需在调用computeToken
函数之前就获取到Gatling Session
中值。
header
方法的第二个参数是value: Expression[String]
,跟踪代码可以看到,Expression
的定义是:type Expression[T] = Session => Validation[T]
。所以之前的一接传入一个字符串其实是由scala
的隐式转换功能将其转换成了下人Expression[String]
的类型(Scala implicit)。
这里就传入一个Session => String
匿名函数,通过session.apply(key)
方法得到一个SessionAttribute
,这样就可以获取到Gatling Session
里的变量了。而.as[String]
方法是获取SessionAttribute
变量的值,并取出为String
类型。
setUp
使用setUp
函数装载写好的测试剧本scenario
,并设置请求用户数(并发数)。.protocols
设置之前定义的http protocol
。
1 | setUp( |
执行测试
在sbt
控制台里使用test
命令执行所有测试脚本,也可以使用testOnly package.Simulation
来指定执行某一个脚本。
生成的测试HTML报告将存放在target/galing
目录。
================================================================================
---- Global Information --------------------------------------------------------
> request count 30 (OK=20 KO=10 )
> min response time 11 (OK=11 KO=12 )
> max response time 61 (OK=61 KO=19 )
> mean response time 20 (OK=23 KO=15 )
> std deviation 12 (OK=14 KO=2 )
> response time 50th percentile 15 (OK=18 KO=14 )
> response time 75th percentile 22 (OK=27 KO=16 )
> mean requests/sec 77.72 (OK=51.813 KO=25.907)
---- Response Time Distribution ------------------------------------------------
> t < 800 ms 20 ( 67%)
> 800 ms < t < 1200 ms 0 ( 0%)
> t > 1200 ms 0 ( 0%)
> failed 10 ( 33%)
---- Errors --------------------------------------------------------------------
> status.find.is(200), but actually found 404 10 (100.0%)
================================================================================
Reports generated in 0s.
Please open the following file: /Users/jingyang/workspace/pressure-suite/target/gatling/cloudsimulation-1438759192370/index.html
[info] Simulation CloudSimulation successful.
[info] Simulation(s) execution ended.
[success] Total time: 30 s, completed 2015-8-5 15:19:53
测试结果就不截图了,有兴趣的朋友可以下载源码,并自行修改后运行查看。
总结
Gatling
是一个强大、易用、可扩展的性能测试利器。现在支持对http
、https
、jms
、sse
等多种协议的支持。Gatling
使用Async Http Client和Netty提供非阻塞的HTTP。用Akka管理Action(请求、暂停、断言等),以及建模和测试流程。