简体   繁体   中英

Gatling 2 how to instrument the DSL

Gatling is a great tool to do load testing, but the DSL somehow baffles me. The problem is that I already have custom request and model classes, and I want to create some kind of "bridge" class to port the existing classes into the DSL.

Here's an example:

exec {
  val request = new GetIdRequest()
  request.setCountry("US")
  request // There is an implicit conversion
    .check(status.is(200), bodyString.saveAs("ids"))
}.exec {
  session => 
    val ids = new ObjectMapper().readValue(session("ids").as[String], classOf[IdList])
    val request = new GetObjectRequest()
    val request.setId(id(0))
    request // There is an implicit conversion
      .check(status.is(200), bodyString.saveAs("object"))
    session
}

where the implicit conversion just converts the request to an http(...).get(url)...

This obviously doesn't work,

  1. session is immutable, so the "object" value isn't saved to session
  2. request in the second exec is not executed, because it's not passed into exec directly

So how can I achieve the desired effect? Is there an example I can adopt, or do I have to implement my own ActionBuilder (I don't want to do this, as this will be like writing another protocol)? Thanks

Update 1

This is the solution I came up with.

I created this translator method

def createHttp(name: String, req: Session => HttpRequest): HttpRequestBuilder = {
  http(name)
    .get {
    session => req(session).getUri
  }
    .header("Content-Type", "application/json")
    .header("Authorization", {
    session =>
      val r = req(session)
      Authorization.create("GET", r.getUri, appId, appKey)
  })
}

Then I just need to pass in a function that creates the HttpRequest

What you didn't understand is that Gatling DSL components are immutable builders that are resolved and chained once and only once when the Simulation is loaded.

As such, you can:

  • neither build requests inside session functions
  • nor manually pass some data that has been resolved from the Session

All those happen at runtime, ie later.

Your first exec works (even though I would advise against a mutable design) because the block content is static the request is indeed built once.

Your second exec actually create a new request builder every time it's executed, but it's just discarded.

If you really want to write your own DSL, you have to embrace how Gatling works. You can't have it only takes resolved values, like your setId , you have to be able to take Expression s too.

Also note that your way of saving the whole response body and creating a new ObjectMapper for every execution is both cumbersome and inefficient.

You could simply use a JsonPath check to grab the single id you're interested in, and then use Gatling EL to inject the saved value into the next request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM