如何为休息json模板编写自定义馈线

时间:2014-12-24 12:16:49

标签: load-testing gatling

我编写了一个简单的“教程”应用程序,它提供了一个名为“世界端点”的REST接口,您可以使用它来添加居民等。这样做的示例json请求可能如下所示:

{
   "name": "Sergio Gonzales",
   "age": "34",
   "languages": [
      { "id": "119" },
      { "id": "14" }
   ],
   "homeland": { "id": "121" },
   "hometown": { "id": "155" }
}

我想添加一个加载测试来测试新居民的“创造”。为了获得数据,我有三个不同的来源:

  1. first_names.csv
  2. last_names.csv
  3. country_capital_language.csv
  4. 前两个将用于创建随机名称(当然,没有高度复杂的方法来创建有意义的数据)。最后一个将用于选择国土,家乡和母语的ID。此外,我会随机选择额外的0 - 3种语言。

    我认为我必须为此编写一个自己的进纸器,但遗憾的是,自发布2.x.x以来,自定义进纸器的文档似乎已经消失。

    写入馈线的好方法是什么?我的第一个想法是直接加载csv数据:

      

    Source.fromInputStream(getClass.getResourceAsStream( “/名称/ first_names.csv”))。getLines.toSet

    不确定使用csv(“first_names.csv”)是否会更好?

    此外我也不知道,如何通过动态创建的数据替换json中的“语言”部分?是否有可能通过语言ID列表并自动转换为有效的json数组?

    UDPATE

    这是我的第一个工作版本。它有缺陷,但它基本上做我想要的。如果有人建议如何增强,请不要犹豫(我对scala很新)。

    package com.u6f6o.apps.hazelnate.load.scenario
    
    import io.gatling.core.Predef._
    import io.gatling.core.feeder.Record
    import io.gatling.http.Predef._
    
    import scala.concurrent.forkjoin.ThreadLocalRandom
    
    class Insert100kInhabitants extends Simulation {
      val random = ThreadLocalRandom.current
      val footprints = csv("data/footprints.csv").records
      val forenames = csv("data/forenames.csv").records
      val surnames = csv("data/surnames.csv").records
    
      val httpConf = http
        .baseURL("http://localhost:4567")
        .acceptHeader("application/json")
        .doNotTrackHeader("1")
    
      val scn = scenario("Insert100kInhabitants").repeat(10000){
        exec{ session =>
          val footprintRecords = chooseRandomly(footprints, 5)
          session.setAll(
            "forename" -> chooseRandomly(forenames).getOrElse("forename", ""),
            "surname" -> chooseRandomly(surnames).getOrElse("surname", ""),
            "age" -> random.nextInt(1, 110),
            "hometown" -> footprintRecords.head.getOrElse("city", ""),
            "homeland" -> footprintRecords.head.getOrElse("country", ""),
            "languages" -> footprintRecords.map{ x => x.getOrElse("language", "")}
          )
        }
        .exec(http("insert100kInhabitants")
          .post("/world/inhabitants")
          .body(StringBody( session => generateJson(session))).asJSON
        )
      }
    
      setUp(
        scn.inject(atOnceUsers(10))
      ).protocols(httpConf)
    
      def generateJson(session:Session) : String = {
        s"""{
          |   "name": "${session("forename").as[String]} ${session("surname").as[String]}",
          |   "age": "${session("age").as[String]}",
          |   "hometown": "${session("hometown").as[String]}",
          |   "homeland": "${session("homeland").as[String]}",
          |   "languages": [
          |     ${session("languages").as[Seq[String]].map{ x => s"""{ "id": "${x}" }"""}.mkString(", ")}
          |   ]
          |}""".stripMargin
      }
    
      def chooseRandomly(pool:IndexedSeq[Record[String]]) : Record[String] = {
        pool(random.nextInt(pool.length))
      }
    
      def chooseRandomly(pool:IndexedSeq[Record[String]], maxLength:Int) : IndexedSeq[Record[String]] = {
        for (i <- 1 to random.nextInt(1, maxLength)) yield pool(random.nextInt(pool.length))
      }
    }
    

2 个答案:

答案 0 :(得分:4)

对于名字和姓氏,请使用简单的馈线。

对于更复杂的数据注入逻辑,请勿使用Feeder。编写自定义exec(function),手动选择记录并将其设置到会话中。您仍然可以使用Gatling的csv解析器来加载数据:

val records: Seq[Map[String, Any]] = csv("country_capital_language.csv").records

由于您需要动态数量的语言,因此您无法使用Gatling EL模板。 您必须手动制作请求正文,请参阅documentation

答案 1 :(得分:1)

到现在为止,Gatling可以自己处理所有这些事情。

注意:我尚未在此处测试简化代码示例。所以请原谅我任何错别字。

  1. JSON中的模板https://groups.google.com/forum/#!topic/gatling/ggR6L4ukmqU。请注意,CSV文件中的列名称必须与模板中的名称相匹配,您需要使用ElFileBody(http://gatling.io/docs/2.2.1/http/http_request.html)。登记/> myTemplate.json

    {
     "name": "${firstName} ${lastName}",
     "age": "34",
     "languages": [
        { "id": "119" },
        { "id": "14" }
     ],
     "homeland": { "id": "121" },
     "hometown": { "id": "155" }
    }
    

    预期的内容,例如: names.csv http://gatling.io/docs/2.2.1/session/feeder.html

    firstName,lastName
    米格尔,普拉多 德克斯特,摩根士 黛博拉,Mrogan

  2. 随机CSV送纸器

    val scn = scenario("Insert100kInhabitants").repeat(10000){
    feed(csv("names.csv").random)
      .exec(http("insert100kInhabitants")
        .post("/world/inhabitants")
        .body(ElFileBody("myTemplate.json").asJSON
      )
    }