Search code examples
testingperformance-testingcucumber-jvmgatling

Programmatically execute Gatling tests


I want to use something like Cucumber JVM to drive performance tests written for Gatling.

Ideally the Cucumber features would somehow build a scenario dynamically - probably reusing predefined chain objects similar to the method described in the "Advanced Tutorial", e.g.

val scn = scenario("Scenario Name").exec(Search.search("foo"), Browse.browse, Edit.edit("foo", "bar")

I've looked at how the Maven plugin executes the scripts, and I've also seen mention of using an App trait but I can't find any documentation for the later and it strikes me that somebody else will have wanted to do this before...

Can anybody point (a Gatling noob) in the direction of some documentation or example code of how to achieve this?

EDIT 20150515

So to explain a little more:

I have created a trait which is intended to build up a sequence of, I think, ChainBuilders that are triggered by Cucumber steps:

trait GatlingDsl extends ScalaDsl with EN {

  private val gatlingActions = new ArrayBuffer[GatlingBehaviour]

  def withGatling(action: GatlingBehaviour): Unit = {
    gatlingActions += action
  }
}

A GatlingBehaviour would look something like:

object Google {

  class Home extends GatlingBehaviour {
    def execute: ChainBuilder =
      exec(http("Google Home")
        .get("/")
      )
  }

  class Search extends GatlingBehaviour {...}

  class FindResult extends GatlingBehaviour {...}
}

And inside the StepDef class:

class GoogleStepDefinitions extends GatlingDsl {

  Given( """^the Google search page is displayed$""") { () =>
    println("Loading www.google.com")
    withGatling(Home())
  }

  When( """^I search for the term "(.*)"$""") { (searchTerm: String) =>
    println("Searching for '" + searchTerm + "'...")
    withGatling(Search(searchTerm))
  }

  Then( """^"(.*)" appears in the search results$""") { (expectedResult: String) =>
    println("Found " + expectedResult)
    withGatling(FindResult(expectedResult))
  }
}

The idea being that I can then execute the whole sequence of actions via something like:

val scn = Scenario(cucumberScenario).exec(gatlingActions)
setup(scn.inject(atOnceUsers(1)).protocols(httpConf))

and then check the reports or catch an exception if the test fails, e.g. response time too long.

It seems that no matter how I use the 'exec' method it tries to instantly execute it there and then, not waiting for the scenario.

Also I don't know if this is the best approach to take, we'd like to build some reusable blocks for our Gatling tests that can be constructed via Cucumber's Given/When/Then style. Is there a better or already existing approach?


Solution

  • Sadly, it's not currently feasible to have Gatling directly start a Simulation instance.

    Not that's it's not technically feasible, but you're just the first person to try to do this. Currently, Gatling is usually in charge of compiling and can only be passed the name of the class to load, not an instance itself.

    You can maybe start by forking io.gatling.app.Gatling and io.gatling.core.runner.Runner, and then provide a PR to support this new behavior. The former is the main entry point, and the latter the one can instanciate and run the simulation.