如何正确地将会话值传递给 gatling 中的方法 feed()

How to pass session values to a method feed() in gatling correctly

我有以下问题。当我尝试执行模拟时,出现此错误:

Generating reports...
Exception in thread "main" java.lang.UnsupportedOperationException: There were no requests sent during the simulation, reports won't be generated
    at io.gatling.charts.report.ReportsGenerator.generateFor(ReportsGenerator.scala:49)
    at io.gatling.app.RunResultProcessor.generateReports(RunResultProcessor.scala:62)
    at io.gatling.app.RunResultProcessor.processRunResult(RunResultProcessor.scala:40)
    at io.gatling.app.Gatling$.start(Gatling.scala:88)
    at io.gatling.app.Gatling$.fromMap(Gatling.scala:41)
    at Engine$.delayedEndpoint$Engine(Engine.scala:11)
    at Engine$delayedInit$body.apply(Engine.scala:4)
    at scala.Function0.apply$mcV$sp(Function0.scala:39)
    at scala.Function0.apply$mcV$sp$(Function0.scala:39)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
    at scala.App.$anonfun$main$adapted(App.scala:80)
    at scala.collection.immutable.List.foreach(List.scala:392)
    at scala.App.main(App.scala:80)
    at scala.App.main$(App.scala:78)
    at Engine$.main(Engine.scala:4)
    at Engine.main(Engine.scala)

Process finished with exit code 1

下面是我的代码:

package simulations

import io.gatling.core.Predef._
import io.gatling.core.scenario.Simulation
import io.gatling.http.Predef._

class Load extends Simulation{

  val httpProtocol = http
    .baseUrl("http://localhost:8080/app/")
    .header("Accept", "application/json")

  val scn = scenario("Scenario").exec(SimpleExample.simple)

    setUp(
      scn.inject(atOnceUsers(3)).protocols(httpProtocol)
    )
}


package simulations

import io.gatling.core.Predef._
import io.gatling.http.Predef._    
import scala.util.Random

object SimpleExample {

  var simple =
    exec(session => session
      .set("rndmSTR", randomString())
      .set("rndmINT", randomInt())
    ).
      exec(
        session => {
          exec(feed(Iterator.continually(Map(
            "game_ID" -> session("rndmINT").as[String].toInt,
            "game_Name" -> session("rndmSTR").as[String]
          ))))
            .exec(
              http("Post New Game")
                .post("videogames/")
                .body(ElFileBody("bodies/newtemplate.json")).asJson
            )
          session
        }
      )

  private def randomString() = {
    new Random().alphanumeric.filter(_.isLetter).take(5).mkString.toLowerCase
  }    
  private def randomInt() = {
    new Random().nextInt(100000)
  }

}

这是我的。json:

{
  "id": "${game_ID}",
  "name": "${game_Name}",
  "releaseDate": "2020-08-11",
  "reviewScore": 99,
  "category": "Driving",
  "rating": "Mature"
}

我知道我可以使用 feed() 方法如下:

package simulations

import io.gatling.core.Predef._
import io.gatling.http.Predef._    
import scala.util.Random    

object NextSimpleExample {

  var rndName: String = null
  var rndID: String = null    
  var feeder = Iterator.continually(Map(
    "game_ID" -> rndID.toInt,
    "game_Name" -> rndName
  ))    

  var simple =
    exec(session => session
      .set("rndmSTR", randomString())
      .set("rndmINT", randomInt())
    ).
      exec(
        session => {
          rndID = session("rndmINT").as[String]
          rndName = session("rndmSTR").as[String]
          session
        }
      )
      .exec(feed(feeder)
        .exec(
          http("Post New Game")
            .post("videogames/")
            .body(ElFileBody("bodies/newtemplate.json")).asJson)
      )

  private def randomString() = {
    new Random().alphanumeric.filter(_.isLetter).take(5).mkString.toLowerCase
  }    
  private def randomInt() = {
    new Random().nextInt(100000)
  }

}

但在这种情况下,所有虚拟用户都将获得相似的值...

此外,我想在接下来的步骤中使用为每个虚拟用户生成的值。例如,将生成的 ID 和名称插入另一个 .json 文件中,用于 post 中的另一个主体或放置请求。 请帮忙解决这个问题。

gatling DSL 定义了一次创建的构建器,因此任何类型的参考代码如

exec(session => session
  .set("rndmSTR", randomString())
  .set("rndmINT", randomInt())
)

将对所有用户产生相同的值。

您的第二个示例实际上是通过转移到普通 Scala 变量来重申第一个示例的复杂方式 - 您仍然只 运行 您的 'random' 函数一次。

但是你很接近 - 如果你将你的随机函数移动到馈线定义中,它将起作用,因为每次调用 .feed 时都会评估这些函数。

var feeder = Iterator.continually(Map(
  "game_ID" -> randomString(),
  "game_Name" -> randomInt()
))    

所以你根本不需要会话函数