u6f*_*f6o 5 load-testing gatling
我写了一个简单的"教程"应用程序,它提供了一个名为"世界端点"的REST接口,您可以使用它来添加居民等.这样做的示例json请求可能如下所示:
{
"name": "Sergio Gonzales",
"age": "34",
"languages": [
{ "id": "119" },
{ "id": "14" }
],
"homeland": { "id": "121" },
"hometown": { "id": "155" }
}
Run Code Online (Sandbox Code Playgroud)
我想添加一个加载测试来测试新居民的"创造".为了获得数据,我有三个不同的来源:
前两个将用于创建随机名称(当然,没有高度复杂的方法来创建有意义的数据).最后一个将用于选择国土,家乡和母语的ID.此外,我会随机选择额外的0 - 3种语言.
我认为我必须为此编写一个自己的进纸器但遗憾的是,自发布2.xx后,自定义进纸器的文档似乎已经消失
写入馈线的好方法是什么?我的第一个想法是直接加载csv数据,如下所示:
Source.fromInputStream(getClass.getResourceAsStream( "/名/ first_names.csv")).getLines.toSet
不确定使用csv("first_names.csv")是否会更好?
除了我也不知道,如何通过动态创建的数据替换json中的"语言"部分?是否有可能通过语言ID列表并自动转换为有效的json数组?
这是我的第一个工作版本.它有缺陷,但它基本上做我想要的.如果有人建议如何增强,请不要犹豫(我对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))
}
}
Run Code Online (Sandbox Code Playgroud)
对于名字和姓氏,请使用简单的 Feeders。
对于更复杂的数据注入逻辑,不要使用 Feeder。编写一个自定义exec(function),您可以在其中手动选择记录并将它们设置到会话中。您仍然可以使用 Gatling 的 csv 解析器来加载数据:
val records: Seq[Map[String, Any]] = csv("country_capital_language.csv").records
Run Code Online (Sandbox Code Playgroud)
由于您需要动态数量的语言,因此您将无法使用 Gatling EL 模板。您必须手动制作请求正文,请参阅文档。