【问题标题】:How to write custom feeder for rest json template如何为 rest json 模板编写自定义 feeder
【发布时间】:2017-01-17 01:35:44
【问题描述】:

我编写了一个简单的“教程”应用程序,它提供了一个名为“世界端点”的 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

前两个将用于创建随机名称(它当然不是创建有意义数据的高度复杂的方法)。最后一个将用于选择家乡、家乡和母语的 id。此外,我会随机选择额外的 0 - 3 种语言。

我假设我必须为此编写一个自己的馈线,但遗憾的是自定义馈线的文档似乎自 2.x.x 版以来已经消失。

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

Source.fromInputStream(getClass.getResourceAsStream("/names/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))
  }
}

【问题讨论】:

  • 你为什么想要一个全球馈线?单独使用有什么问题?
  • 哦,我不知道您可以同时分配多个馈线。会试一试。谢谢提示。
  • feed(feeder1).feed(feeder2).feed(feeder3)
  • 对于名字和姓氏馈线,这非常有效。对于最后一个馈线(country_city_language),我想返回一个记录列表,比如说 1 - 4 随机。对于其中一个,我会选择国家和城市信息,另外还会从其他记录中选择 1-4 种语言的列表。在提到的 json 模板中是否有一种很好的方法来转换它?
  • 查看当前文档,其中提到了如何创建自定义馈线。根据gatling.io/docs/2.1.4/session/feeder.html,“Feeder 是Iterator[Map[String, T]] 的类型别名”,因此您可以执行以下操作:val feeder = Iterator.continually(Map("email" -&gt; (Random.nextString(20) + "@foo.com")))

标签: load-testing gatling


【解决方案1】:

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

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

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

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

【讨论】:

  • 正是我想要的!谢谢,圣诞快乐!
  • 我添加了我的第一个工作版本。如果您能给我一些提示,我将不胜感激,因为我认为存在一些缺陷:-)
  • 你不需要getClass.getResource(path).getFile。 csv 将尝试不同的策略来解析位置。其中之一在类路径中。然后,我会使用更多的字符串插值。
  • 按照你的建议做了。谢谢
【解决方案2】:

现在 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.csvhttp://gatling.io/docs/2.2.1/session/feeder.html

    名字,姓氏
    米格尔,普拉多
    德克斯特,摩根
    德博拉,莫罗根

  2. 随机 CSV 馈送器

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 2012-11-06
    相关资源
    最近更新 更多