Programmatically execute Gatling tests
Asked Answered
A

2

6

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?

Ammeter answered 12/5, 2015 at 14:56 Comment(0)
I
5

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.

Igloo answered 12/5, 2015 at 22:41 Comment(1)
Thanks, I've seen that but it looks like it loads static Gatling scripts not being passed a dynamically generated Scenario - am I missing something?Ammeter
P
4

I recently ran into a similar situation, and did not want to fork gatling. And while this solved my immediate problem, it only partially solves what you are trying to do, but hopefully someone else will find this useful.

There is an alternative. Gatling is written in Java and Scala so you can call Gatling.main directly and pass it the arguments you need to run the Gatling Simulation you want. The problem is, the main explicitly calls System.exit so you have to also use a custom security manager to prevent it from actually exiting. You need to know two things:

  1. the class (with the full package) of the Simulation you want to run example: com.package.your.Simulation1
  2. the path where the binaries are compiled.

The code to run a Simulation:

protected void fire(String gatlingGun, String binaries){
    SecurityManager sm = System.getSecurityManager();
    System.setSecurityManager(new GatlingSecurityManager());
    String[] args = {"--simulation", gatlingGun,
            "--results-folder", "gatling-results",
            "--binaries-folder", binaries};
    try {
        io.gatling.app.Gatling.main(args);
    }catch(SecurityException se){
        LOG.debug("gatling test finished.");
    }
    System.setSecurityManager(sm);
}

The simple security manager i used:

public class GatlingSecurityManager extends SecurityManager {
    @Override
    public void checkExit(int status){
        throw new SecurityException("Tried to exit.");
    }
    @Override
    public void checkPermission(Permission perm) {
        return;
    }
}

The problem is then getting the information you want out of the simulation after it has been run.

Pennon answered 17/3, 2016 at 21:51 Comment(2)
i am into similar situation @Pennon could you provide detailed solution,i desperately need gatling simulation to run as a java code #60313366Salientian
@markliberhman sorry for the delay, I didn't notice I had a message because I didn't notice I was logged in. The question in the link in your comment does not appear to have been removed. Without knowing your project set up I can't provide a more detailed solution. But all you have to do is call the fire method with a call like: fire(GatlingTestClass.getClass().getCannonicalName(), "build")Pennon

© 2022 - 2024 — McMap. All rights reserved.