Thursday, February 21, 2019

How to use array input parameters with ForEach Controller in JMeter

It is a very basic and common request that run calls base on input array in Jmeter scripts. ForEach Controller can iterates through an array of variables and invoke the actions below it basing on each value.

In this tutorial, we will talk about below situations with using the ForEach Controller.

Case A: convert a input string and use it in ForEach Controller
Case B: Parse a JSON response and use it in ForEach Controler

Definition of FroEach Controller

Before we start, let's see the official defines for FroEach Controller.
A ForEach controller loops through the values of a set of related variables. When you add samplers (or controllers) to a ForEach controller, every sample (or controller) is executed one or more times, where during every loop the variable has a new value. The input should consist of several variables, each extended with an underscore and a number. Each such variable must have a value. So for example when the input variable has the name inputVar, the following variables should have been defined:
  • inputVar_1 = wendy
  • inputVar_2 = charles
  • inputVar_3 = peter
  • inputVar_4 = john
Note: the "_" separator is now optional.
The ForEach Controller does not run any samples if inputVar_1 is null. This would be the case if the Regular Expression returned no matches.

From the definition we know that FroEach Controller accept a set of variables which have the same prefix and formatted as Name_IndexNumber, the index starts from 1.And it will pass each value into all he Samples in the loop. And ForEach Controller will not run if the first value is null.

Case A: convert a input string and use it in ForEach Controller

Suppose there is an input value as "a,b,c,d", how could we use it in the ForEach Controller? First, we need to parse the input and add it into a set of variables.
Here is the JSR223 Sample "Sample 3" that we use for this tutorial"inputValue"));
String[] testvars = (props.get("inputValue")).split(",");
vars.putObject("inputVarA", testvars);

String[] testv = vars.getObject("inputVarA");
for(int i = 0; i < testv.length; i++) {
    vars.put("inputVarB_"+(i+1), testv[i]);
It reads the parameter inputValue, and split it into a string array. inputVarA is stored as an object in jmeter while in the for loop, we store each value into a new variable as inputVarB_[index]. And then We create two ForEach Controller, first one is using inputVarA

And the second one is using inputVarB
And run it, we will see

The foreach loop which using inputVarB runs successfully while the one using inputVarA does not run.Which approved that ForEach Controller only accept the input format as Name_indexNo.

Case B: Parse a JSON response and use it in ForEach Controler

Then, what if I want to use a JsonArray as the input for the ForEach Controller, as Json is a very common response format for the web service.

Suppose we have an API returns the response as below
[{id:1, attributeName:a},{id:2, attributeName:b},{id:3, attributeName:c},{id:4, attributeName:d}]
And we want to use the attributeName as the input for ForEach Controller.
To extract all the attributeName, we need to use the JSON Extractor.
And then use it as the input at the ForEach Controller
Run it, you will see the values in the attributeName has been used in ForEach loop.
Somebody may ask how the ForEach Controller recognize the extract variable? as there is no steps to add in the underscore and number after it. This is because the JSON Extractor automatically stores the extract value as the format of VariableName_Index.
Use a JSR223 to verify this:"log for input vars_1: " + vars.get("inputVar_1"));"log for input vars list: " + vars.getObject("inputVar"));
And we will get the log as below at debug view:
 INFO  - jmeter.extractor.JSR223PostProcessor: log for input vars_1: a
 INFO  - jmeter.extractor.JSR223PostProcessor: log for input vars list: null
For more information about how JSON Extractor work, please refer the doc here.

1 comment :

  1. The much more elegant way to generate a list of XXXX_NN vars for forEach conroller using Groovy:

    variablesList.eachWithIndex { it, idx ->
    vars.put("var_${idx + 1}", it)