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(请求、暂停、断言等),以及建模和测试流程。