How to Pass an Array from a JSR223 Sampler to Another JSR223 Sampler? - jmeter

I just want to know how to pass an array from a JSR223 sampler to another JSR223 sampler. Note that the two JSR223 are just in the same thread. I had been searching and I cannot find the exact solution. I'm just a newbie in Jmeter, just searching for java codes etc. So here is the code:
import groovy.json.JsonSlurper;
String response = prev.getResponseDataAsString();
def jsonSlurper = new JsonSlurper();
def json = jsonSlurper.parseText(response);
int size = json.records.size;
vars.put("intDashboardMeetingsCount", size);
def strMeetingsArray = new String[size];
if (size > 0) {
for (int i=0;i<size;i++) {
strMeetingsArray[i] = json.records.get(i).id;
}
}
I already got the number of records in intDashboardMeetingsCount, and I just need to know how will I able to get the data of strMeetingsArray[]
Thanks in advance!

Just use vars shorthand, it stands for JMeterVariables class instance so you should be able to use vars.putObject() function in order to add your strMeetingsArray to JMeter Variables and vars.getObject() to retrieve it.
So in 1st JSR223 Sampler:
vars.putObject('somevar', strMeetingsArray)
in 2nd JSR223 Sampler:
def strMeetingsArray = vars.getObject('somevar')
More information: The Groovy Templates Cheat Sheet for JMeter

you can use variables (vars) for a single thread. When you do a multi-thread test, you can use the properties (props).
Sample Variable Used Javascript Code:
vars.put("myString","mysamplestring");
var getString= vars.get("myString");
var array = ['bilal','demir'];
vars.putObject("myArray",array);
var getArray = vars.getObject("myArray");
log.info( "*getString : {} *getArray :{} *firstItem: {} *length : {}" , getString, getArray, getArray.length, getArray[0]);
//output: *getString : mysamplestring *getArray :{0=bilal, 1=demir} *firstItem: bilal *length : 2
Sample Properties Used Javascript Code:
var array = ['bilal','demir'];
props.put("myArray",array);
var getArray = props.get("myArray");
log.info( "getArray :{} length : {}" , getArray, getArray.length);
//output: getArray :{0=bilal, 1=demir} length : 2
For groovy change define variable code var to def

Related

How to get multiple values from a CSV file inside of one test iteration

I need to dynamically generate an XML or JSON in an iteration where the XML or JSON has a variable number of elements -- e.g., it could be books. The values of the books come from the CSV file.
I created a CSV Data Config that point to the CSV file with a variable called csvBook.
Next, in a BeanShell Sampler, I call
StringBuffer sb = new StringBuffer("<Order><Books>");
Random rv = new Random();
int size = rv.nextInt(100);
for (int i = 0; i < size; i++) {
sb.append("<Book Name=" + vars.get("csvBook") + "/>");
}
sb.append("</Books></Order>");
The problem is I don't know how to get new values from the CSV file as I run through the loop inside one iteration. The vars.get("csvBook") returns the same value in the same iteration.
Is there a command to tell JMeter to get the next CSV value (next row) (again, inside one iteration)?
Thanks in advance.
Consider switching to JSR223 Sampler and Groovy language as:
Groovy has built-in support for JSON
Groovy has built-in support for XML
Groovy performance is much better than Beanshell
The relevant Groovy code would be something like:
import groovy.xml.StreamingMarkupBuilder
def csvFile = new File('/path/to/csv/file')
def payload = {
order {
books {
csvFile.readLines().each {line ->
book (name:line)
}
}
}
}
def xmlFile = new File('/path/to/xml/file')
def writer = xmlFile.newWriter()
def builder = new StreamingMarkupBuilder()
def writable = builder.bind payload
writable.writeTo(writer)

How to use ForEach controller on an array?

jmeter ForEach controller can be used to iterate over variables with same prefix like,
myVar_1
myVar_2
myVar_3
But in my case input variable is array of strings, [ "val1", "val2", "val3" ] How to iterate over an array and send separate request for each value?
You won't be able to feed this JSON Array to the ForEach Controller, but you can convert it into a form which can be understood by the ForEach Controller
Add a JSR223 Sampler after the variable holding this JSON Array is defined
Put the following code into the "Script" area:
def json = new groovy.json.JsonSlurper().parseText(vars.get("yourInputVariable"))
def counter = 1
json.each {
vars.put("myVar_" + counter, it)
counter++
}
Replace yourInputVariable with the actual name of the variable holding the JSON Array
Add ForEach Controller under the JSR223 Sampler and perform "normal" configuration as you would do it for myVar_1, myVar_2,... - it will work fine as JSR223 Sampler creates the relevant variables basing on the data from the JSON Array.
See Parsing and producing JSON - Groovy and Groovy Is the New Black articles for more information.
Same way as you use for same prefixed variables.
For variable myVar
myVar = ["val1", "val2", "val3"];
//Following variables are automatically created
myVar_1 = "val1";
myVar_2 = "val2";
myVar_3 = "val3";
ForEach controller will be used on myVar_1, myVar_2, myVar_3
Use Debug Sampler to ensure.
jmeter version : 3.1 r1770033
I tried Dmitri's answer, but basically got stuck with the groovy script as it works only for a simple array of strings. I, however, needed a more complex array of JSON objects.
Then I switched the scripting language to ecmascript and based on the original script wrote a good old JS like this:
var jsonObject = JSON.parse(vars.get("ReportSources"));
for(var index = 0; index < jsonObject.length; index++) {
vars.put("rs_" + (index + 1), JSON.stringify(jsonObject[index]));
}
It worked for me.

Exclude blank values from csv file for JSON array in Jmeter

I have jsonarray as [foodid1,foodid2,foodid3] .The values of these are reading from a csv file
csv file content
foodid1,foodid2,foodid3
10,12,14
if I don't want to pass the value to foodid2, the JSON array is being passed as [10,,14]
Instead, I wanted it to be passed as [10,14].
following is the JSON body:
customerdetails={
"regDate":${regDate},
"regNo":"${regNo}",
"firstName":"${fname}",
"lastName":"${lname}",
"dateOfBirth":"${dob}",
"bloodGroupId":0,
"mobileNo":"${mobile}",
"residenceNo":"${resdno}",
"officeNo":"${officeno}",
"email":"${email}",
"address1":"${adr1}",
"address2":"${adr2}",
"pincode":"${pin}",
"stateId":${stateid},
"city":"${city}"}
&customerhistory={
"historyId":[${food1},${food2},${food3},${food4}]}
how can I handle this situation in Jmeter
Thanks in Advance
The easiest solution would be replacing double commas with single commas on the fly using Beanshell PreProcessor
Add Beanshell PreProcessor as a child of the HTTP Request you're going to modify
Put the following code into the PreProcessor's "Script" area:
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.config.Argument;
import org.apache.jmeter.protocol.http.util.HTTPArgument;
Arguments oldArgs = sampler.getArguments();
Arguments newArgs = new Arguments();
for (int i = 0; i < oldArgs.getArgumentCount(); i++) {
Argument argument = oldArgs.getArgument(i);
String oldValue = argument.getValue();
String newValue = oldValue.replaceAll(",,", ",");
newArgs.addArgument(new HTTPArgument(argument.getName(), newValue));
}
sampler.setArguments(newArgs);
When you will run your test the PreProcessor will replace ,, with , for each parameter value.
See How to Use BeanShell: JMeter's Favorite Built-in Component article for more information about using Beanshell in JMeter tests.

loop through array values in jmeter Json path and assert each value

I have this filtered JSON response from Json Path exression
[40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,45,45,45,45,45,42,45,42,45,42,41,40,35,37,35,45,42,41,40,35,37,35,45,42,41,40,35,37,35,45]
I need to write some assertion which will basically assert these values are in a range ex: between 30 and 60.
I am not getting any pointers on how to assert this in jmeter.
JMeter doesn't offer appropriate Test Elements so you will have to do some scripting.
The below code assumes JMeter version is equal or higher than 3.0. For earlier JMeter versions you will have to put Json-smart libraries somewhere in JMeter Classpath
Add Beanshell Assertion after the JSON Path PostProcessor
Put the following code into the Beanshell Assertion "Script" area
import net.minidev.json.JSONArray;
import net.minidev.json.parser.JSONParser;
import org.apache.commons.lang.math.IntRange;
String source = vars.get("yourVar");
IntRange range = new IntRange(30, 60);
JSONParser parser = new JSONParser(JSONParser.MODE_JSON_SIMPLE);
JSONArray array = (JSONArray) parser.parse(source);
for (int i = 0; i < array.size(); i++) {
int value = (int) array.get(i);
if (!range.containsInteger(value)) {
Failure = true;
FailureMessage = "Detected value: " + value + " is not in the expected range";
}
}
If the value outside the given range will be found the Beanshell Assertion will fail the parent sampler
See How to Use BeanShell: JMeter's Favorite Built-in Component article for more information on enhancing your JMeter tests with scripting.

jmeter json path bean post processor

I have following entries that got extracted from Response using JSONPath extractor
entries = ["e-1553","e-1552","c-1052","e-1551","c-1050",
"e-1550","c-1049","e-1549","c-1051","e-1548",
"c-1048","e-1547","c-1047","e-1546","c-1045",
"e-1545","e-1544","c-1046","e-1543","e-1542",
"c-1026","e-1541","e-1540","e-1539","e-1538",
"c-1025","e-1537","e-1536","c-1024","f-1535",
"f-1534"]
I want to Iterate only over those entries that start with "e-" e.g. "e-1553,e-1552" etc. in my ForEach Controller and exclude other entries such as "c-1052, c-1050" etc.
So that I can use http://somesite.com/e-1553 etc.
How do I do that?
Given you have "entries" variable which holds that JSONArray you can get all the entries which start from "e-" as follows:
Add a Beanshell PostProcessor after the JSONPath Extractor
Put the following code into the PostProcessor's "Script" area:
JSONArray array = JSONArray.fromObject(vars.get("entries"));
int counter = 0;
for (int i=0;i < array.size();i++) {
String s = array.get(i).toString();
if (s.startsWith("e-"))
{
counter++;
vars.put("entry_" + counter, s);
}
}
It will produce variables like:
entry_1=e-1553
entry_10=e-1544
entry_11=e-1543
entry_12=e-1542
entry_13=e-1541
etc.
Then add ForEach Controller and configure it as follows:
Input variable prefix: entry
Start index for loop: 0
Output variable name: current_entry
Then in HTTP Request use ${current_entry} in the Path.
See How to use BeanShell: JMeter's favorite built-in component guide for more information on Beanshell scripting in JMeter.

Resources