Functional tests - Passing context between simulations

Hi,

I’m new to Gatling (and Scala) after struggling with one of my functional validation plan I’ve started to write on JMeter, in particular, around chaining requests to reflect use cases.
At this time, this is mostly functional tests (I know Gatling and JMeter are best for load tests).

After one day spent with Gatling, as a developer and an old JMeter user, I can see the benefits and like to go further but I’d like to get recommendation first.

Actually, here’s a simplified view of the use cases I want to simulate over a HTTP REST API:

  1. creating multiple users (facebook test users)
  2. login them to our backend and obtaining session tokens
  3. simulate users following other users, using session tokens
  4. check list of followers / following are ok for each user
  5. delete the users on Facebook and our backend

I’ve created most of the steps as separate chains and used multiple Maven executions to run them (on a single user at this time).
Great !

However, as there’s no real sequence (and reading other posts, I understand why), I’d like to know how best I can implement passing contexts between chains in separate simulations.
Generating CSV? Custom feeder? Saving session attributes ? Any recommendation?

Thanks,
Fabrice

Hi,

I see two ways:

  • Have all these steps be distinct simulations, like you did. If so, yes, the best way to pass context from one to another is probably to store session data into a temp file as a last step of a simulation, and use it as a feeder in the next one.
  • Consider that those steps are processes, but are to be chained into a global simulation. You can build processes libraries (for example declare them in Scala objects, import them and compose simulations out of them). You can even wrap them in groups so you can get stats for each process.
    Am I being clear?

Cheers,

Stéphane

Hi Stéphane and thanks,

I understand option 1 - persisting session data + feeder to chain simulation through different executions.

I’m not sure to quite understand option 2 - building a global simulation chaining processes.
I think that would ease but I’m not sure about feasibility for my use cases.
Let’s imagine I have something like:

setUp(createUser.exec(validate).exec(deleteUser).inject(atOnce(10 users))).protocols(httpPrefs)

As far as I understand, the number of users is injected concurrently for the whole simulation.
So, the “validate” chain would be unable to simulate “follow” actions between created users as everything (creation, validation, deletion) is executed concurrently and driven by the number of users.

Am I right or have I missed something ?

Thanks,
Fabrice

OK, get it.

Would introducing rendez-vous points helps?

val created = new AtomicInteger(0)

// create

.exec(session => created.incrementAndGet; session)
.asLongAs(session => created.get < 10) {
pause(1)
}
// validate

Hi,

Thanks, the rendez-vous points works fine.
I’m starting to understand the Gatling way and like it, even if I understand it is mainly focused today for stress tests, not functional as I’m trying to.

After playing during the week, I now have the following problems:

  1. I use the following when I need to check the “result” attribute from my JSON response is an empty array. But it fails with “jsonPath($.result).is(0) didn’t match: found nothing” (btw count is removed). I also tried running it against latest code from Github.


.check(status.is(200), jsonPath(“$.result”).count.is(0)))

  1. I’ve tried using exitHereIfFailed after an execution with session.markAsFailed to do intermediate checks around several associated requests. Actually, I’d like to make my scenario stop and fail depending on some conditions at some point, gathering data coming from several HTTP requests. I must have done something bad. Do you have any recommendation?

Thanks,
Fabrice

Thanks, the rendez-vous points works fine.

Glad to hear :slight_smile: Things sometimes don't work as expected when you code them
in an email...

I'm starting to understand the Gatling way and like it, even if I
understand it is mainly focused today for stress tests, not functional as
I'm trying to.

Well, yes, but using the same tool, or even better the same tests for
performance and functional testing completely makes sense to me. You're not
the first one to go that way:
http://devblog.orgsync.com/rest-api-integration-testing-with-gatling

We haven't pushed very far in this direction yet (limited resources,
priorities), but we'd gladly take any feedback in this field.

After playing during the week, I now have the following problems:

1) I use the following when I need to check the "result" attribute from
my JSON response is an empty array. But it fails with
"jsonPath($.result).is(0) didn't match: found nothing" (btw count is
removed). I also tried running it against latest code from Github.

...
.check(status.is(200), jsonPath("$.result").count.is(0)))
...

2) I've tried using exitHereIfFailed after an execution with
session.markAsFailed to do intermediate checks around several associated
requests. Actually, I'd like to make my scenario stop and fail depending on
some conditions at some point, gathering data coming from several HTTP
requests. I must have done something bad. Do you have any recommendation?

Thanks,
Fabrice

Could you try latest snapshot, please? Those issues might have already been
fixed.
https://oss.sonatype.org/content/repositories/snapshots/io/gatling/highcharts/gatling-charts-highcharts/2.0.0-SNAPSHOT/

You'll have some small migration effort though.
If you need help, just ask.

  1. I use the following when I need to check the “result” attribute from my JSON response is an empty array. But it fails with “jsonPath($.result).is(0) didn’t match: found nothing” (btw count is removed). I also tried running it against latest code from Github.

Could you try latest snapshot, please? Those issues might have already been fixed.
https://oss.sonatype.org/content/repositories/snapshots/io/gatling/highcharts/gatling-charts-highcharts/2.0.0-SNAPSHOT/

You’ll have some small migration effort though.
If you need help, just ask.

Hi,

I’ve got exactly the same issue than “1)” so I try to use the 2.0.0-SNAPSHOT but i cannot succeed to migrate my project.
Are there some migration docs somewhere ?

Thanx

What are your errors?

cheers

Thanx to this page: https://github.com/excilys/gatling/wiki/Gatling-2
And the examples I manage to transform almost all my scenarios ! :slight_smile:

I’m just getting stuck with the old upload method:

.exec(http(“Upload photo”)
.post("/somewhere")
.upload(“photo”, “photo.png”)
.check(status.is(200))
)
value upload is not a member of io.gatling.http.request.builder.HttpRequestWithParamsBuilder

Thanx for quick answer !

upload was only reintroduced in upcoming version.

You have to use a RawFileBody (and set the Content-Type to multipart/form-data)

Big thanx :slight_smile:

With your advices i come up with:

.exec(http(“Upload photo”)
.post(“/somewhere”)
.header(“Content-Type”, “multipart/form-data”)
.bodyPart(RawFileBodyPart(“photo”, “photo.png”).contentType(“image/png”).fileName(“photo.png”))
.check(status.is(200))
)

And it work fine !

Nice :slight_smile:

Hope you don’t mind me picking up an old thread. This thread went over to focus on option #2, but I’m curious about option #1. How would you recommend doing this? More specifically, I’m wondering:

  • How would you know where to write this temp file to? I.e., you would want to write it to the gatling bodies folder, but that is configurable. What is the best way to inspect what the configured bodies folder is?
  • How would you clean up this temp file?