Looping over an array from a JSON response

I’m trying to use Gatling to test a JSON web service. I’ve got the basics of posting and parsing the JSON data working, but for the life of me I can’t figure out the next step. I want to have the test scenario entirely driven from data returned by the service.

Essentially I have a two step scenario. Step 1 retrieves a JSON array from the service and I want step 2 to either pick the (up to) first 10 elements of the array, or better, 10 random elements from the array. I can parse the response like this:

.check(jsonPath("/facets/keywords/terms").saveAs(“keywords”))

And that seems to work, but I can’t figure out how to treat the “keywords” session variable as a List and iterate it for the next scenario. It seems like I could use a Feeder, but they don’t really seem to suit per-request data.

Any clues?

Cheers,
Dan

Hi Dan,

You’re not the one at fault: we are…

Currently, you can’t neither use a feeder as the only built-in implementation are shared among users, nor use a loop.times are the number of times is currently static (see https://github.com/excilys/gatling/issues/376).

I could point you to a Scala based solution but let me see if I can find out a better solution and have it shipped in 1.1.4 that I would like to release today.

Cheers,

Steph

2012/4/23 Dan Everton <dan@iocaine.org>

Hi again,

I’ve been giving more thoughts about your questions.

Generally speaking, Feeders are not intended to be control structures ala Tsung. When we designed them, we decided that injecting external data into the session and looping were 2 different responsibilities. As a consequence, we don’t have an implementation that loops on a feeder as long as it returns data. Moreover, Feeders are currently intended to be shared among users. Changing this would be quite impacting, so we’ll only consider doing it if more people ask for it.

Regarding your use case, first of all, your check is wrong. As explained here in the doc, what you probably want is actually:
.check(jsonPath("/facets/keywords/terms").findAll.saveAs(“keywords”))

Then, let’s do some Scala!
https://gist.github.com/2469375

Tell me if you need further explanation.

Cheers,

Stephane

2012/4/23 Stéphane Landelle <slandelle@excilys.com>

Generally speaking, Feeders are not intended to be control structures ala Tsung. When we designed them, we decided that injecting external data into the session and looping were 2 different responsibilities. As a consequence, we don’t have an implementation that loops on a feeder as long as it returns data. Moreover, Feeders are currently intended to be shared among users. Changing this would be quite impacting, so we’ll only consider doing it if more people ask for it.

I believe this would be a common use case for testing web services where user interaction modifies the data set being returned. For a lot of our load testing, we use data that’s already in the application and can’t pre-compute or rely on pre-stored values. Or the data sets involved are too large to include in the test and we load them out-of-band. Basically it would be really good to have some sort of user level Feeder structure that would allow a single user to modify their behaviour and use data from the application.

Regarding your use case, first of all, your check is wrong. As explained here in the doc, what you probably want is actually:

.check(jsonPath(“/facets/keywords/terms”).findAll.saveAs(“keywords”))

Argh! I totally missed the extraction bit of the documentation. That’s what I get for skimming. That one change and rereading the Checks documentation has made a lot of difference.

Then, let’s do some Scala!
https://gist.github.com/2469375

Thanks for that example it makes things very clear now and is exactly what I needed.

Cheers,
Dan

Generally speaking, Feeders are not intended to be control structures ala
Tsung. When we designed them, we decided that injecting external data into
the session and looping were 2 different responsibilities. As a
consequence, we don't have an implementation that loops on a feeder as long
as it returns data. Moreover, Feeders are currently intended to be shared
among users. Changing this would be quite impacting, so we'll only consider
doing it if more people ask for it.

I believe this would be a common use case for testing web services where
user interaction modifies the data set being returned. For a lot of our
load testing, we use data that's already in the application and can't
pre-compute or rely on pre-stored values. Or the data sets involved are too
large to include in the test and we load them out-of-band. Basically it
would be really good to have some sort of user level Feeder structure that
would allow a single user to modify their behaviour and use data from the
application.

Yep, just that we didn't intended Feeders this way, so we're in position of
having to chose between breaking things, introduce a new API or explain how
to write it with Scala functions.
See below why.

Regarding your use case, first of all, your check is wrong. As explained
here <GitHub - gatling/gatling: Modern Load Testing as Code; in
the doc, what you probably want is actually:
.check(jsonPath("/facets/**keywords/terms")*.findAll*.**
saveAs("keywords"))

Argh! I totally missed the extraction bit of the documentation. That's
what I get for skimming. That one change and rereading the Checks
documentation has made a lot of difference.

Then, let's do some Scala!
https://gist.github.com/**2469375 <https://gist.github.com/2469375&gt;

Thanks for that example it makes things very clear now and is exactly what
I needed.

Glad to hear!

Things will actually become even more simple once we'll get rid of
Make loop.times value dynamic · Issue #376 · gatling/gatling · GitHub (that's why I'm reluctant to
breaking the Feeder API for this) and if you can give up on what is very
specific (getting the max 10 results and randomize). You'll be able to
write something like this:
https://gist.github.com/2474278

Cheers,

Steph