Gatling 测试工具学习

Gatling是一款基于Scala 开发的高性能服务器性能测试工具,它主要用于对服务器进行负载等测试,并分析和测量服务器的各种性能指标。Gatling主要用于测量基于HTTP的服务器,比如Web应用程序,RESTful服务等,除此之外它拥有以下特点:

  • 支持Akka Actors 和 Async IO,从而能达到很高的性能

  • 支持实时生成Html动态轻量报表,从而使报表更易阅读和进行数据分析

  • 支持DSL脚本,从而使测试脚本更易开发与维护

  • 支持录制并生成测试脚本,从而可以方便的生成测试脚本

  • 支持导入HAR(Http Archive)并生成测试脚本

  • 支持Maven,Eclipse,IntelliJ等,以便于开发

  • 支持Jenkins,以便于进行持续集成

  • 支持插件,从而可以扩展其功能,比如可以扩展对其他协议的支持

  • 开源免费

Gatling适用的场景包括:测试需求经常改变,测试脚本需要经常维护;测试环境的客户机性能不强,但又希望发挥硬件的极限性能;能对测试脚本进行很好的版本管理,并通过CI进行持续的性能测试;希望测试结果轻量易读等。

其他详解:http://www.infoq.com/cn/articles/new-generation-server-testing-tool-gatling/

使用安装

   最新版本2.0.1  

   sbt构建  "io.gatling.highcharts" % "gatling-charts-highcharts" % "2.0.1"(GutHub应保存构建模板)  

   安装相对来说比较简单,根据自己系统下载相应的zip包,解压至安装目录,配置系统环境变量GATLING_HOME(WIN)

   配置好环境变量后,在目录bin下有gatling.bat or gatling.sh运行脚本,运行成功后会提示用户选择测试脚本

   运行成功后,会在/$gatling/results生成本次测试数据:曲线图、请求响应时间等方便查看结果统计。

使用技巧:

   目前使用Gatling 1.5.6版本居多,但与2.0.1版本变化有明显差别,加入DSL等特性,具体详细

   参见: http://gatling.io/docs/2.0.1/project/migration_guides/1.5.x-to-2.0.html#x-to-2-0

   api doc: http://gatling.io/docs/2.0.1/

   Gatling DSL:http://gatling.io/docs/2.1.4/cheat-sheet.html

使用中遇到的问题:

   Q:如何对请求追加请求参数

   A:对于scala来说可以用queryParamMap(Map[String,Any])来对请求方便的增加请求参数(get请求可以将map转换为K=V 的String),当然还有单个传参queryParam(String,String)等,可参考:query-parameters

   Q:需要对请求后的结果进行检测或校验

   A:使用check 如 check(status.is(200)),check(regex(""""<.*>""").findAll.exsits)

   Q: 怎么对请求后响应的结果进行操作?操作如:将结果set到session中?

   A: 上例子会更明白些,案例说明:获取用户喜欢的所有topics根据每个topic的id请求相应id的推荐
   
val ranking = scenario("just test userLike")
    .exec(http("userLikeTopic").get("user/general_men/like.json").queryParamMap(params)
    .check(status.is(200), jsonPath("$.datas[*]").ofType[Map[String,Any]]//jsonPath         

    .findAll.saveAs("likeTopics"))).foreach("${likeTopics}", "topics") {

        exec(session => {

                val topics = session("topics").as[Map[String, Any]]
                session.set("cid", topics("cid"))
        })
    .pause(2, 5)
    .exec(http("ranking") get ("topic/${cid}/rankings.json") queryParamMap (params)//可以更换为page请求
   }

   //设置一个用户请求 设置大于1时,是指N个用户并发访问,当然Gatling也提供了另外一种配置来解决,"多用户但并不同时并发访问" inject(rampUsers(n) over (n times))   

   setUp(ranking.inject(atOnceUsers(1)).protocols(httpConf))

   Q:请求api时会有分页的操作,如何使用Gatling来实现分页的测试功能

   A:Gatling 提供了Loop statements repeat函数,来看下这个函数的定义

        repeat(times,counterName){chain}

        //times 可以是Int值,指向Session("${}")的EL字符串,或者是一个表达式Expression[Int]

        //counterName 可选,可用来标记当前循环计数器的名称。需要注意的是默认开始是0

        官方给的小样例: 1- repeat(20){chain}//循环20次  2- repeat("${page}"){chain} //从session属性中取出page的值循环  3- repeat(session => session("page").as[Int]) //同2

          有了这个函数就可以简单的实现分页测试,但是程序往往不会设计像这样,如我的项目中使用了字符串、Int值、时间戳来控制分页请求,显然这样的功能是不能满足,对此我们只需要借助repeat函数来控制外层(预期的循环次数)

          使用Gatling为我们提供Conditional statements 中  提供的

def doIfOrElse(condition: Expression[Boolean])(thenNext: ChainBuilder)(elseNext: ChainBuilder): B = doIf(condition, thenNext, Some(elseNext))

        修改后为

def buildPaging(actionTitle: String, thenUrl: String, attributeKey: String = "last_pos", loopTimes: Int = 5) = {
 loopWithCondition(session => !session.contains(attributeKey), loopTimes) {
   exec(http(actionTitle) get thenUrl check(status.is(200), jsonPath("$.last_pos").saveAs(attributeKey)))//偷懒 jsonPath可以作为一个参数传入
 } {
   exec(http(actionTitle) get (thenUrl + "&start=${" + attributeKey + "}") check(status.is(200), jsonPath("$.last_pos").saveAs(attributeKey)))
 }.exec(session => session.remove(attributeKey)).pause(50.milli)
}

def loopWithCondition(condition: Expression[Boolean], times: Int)(thenNext: ChainBuilder)(elseNext: ChainBuilder) =
 repeat(times)(doIfOrElse(condition)(thenNext)(elseNext))



   后续整理中...


你可能感兴趣的:(scala,gatling)