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

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)

Related

Iterating over each row and accessing every column in HTTP Sampler in JMeter

I have explored and tried solution mentioned on Google or StackOverflow but could not solve my problem.
I am trying to iterate over each row of CSV and use every column of a row in "HTTP Sampler"
This is what I have tried till now.
My Test plan structure
This is my CSV file
This is my CSV Data Set Config
I am reading entire CSV and storing values in JMeter properties variable using Bean Shell Sampler.
This is the code in Bean Shell Sampler
import java.text.*;
import java.io.*;
String filename = "load_test_date.csv";
ArrayList strList = new ArrayList();
try{
log.info("starting bean shell");
File file = new File(filename);
if(!file.exists()){
throw new Exception ("ERROR: file " + filename + " not found");
}
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
log.info("while loop starting");
headerLine = br.readLine();
while((line = br.readLine())!=null){
log.info(line);
String[] variables = line.split(",");
props.put("header_1",variables[0]);
props.put("header_2",variables[1]);
props.put("header_3",variables[2]);
props.put("header_4",variables[3]);
props.put("header_5",variables[4]);
}
}catch(Exception ex){
log.error(ex.getMessage());
}
Now I want to iterate over props variable and fetch each column. I tried using While controller and ForEach Controller, but it is not giving me desired output.
while controller
While loop is executing twice (instead of three times for three rows in csv file) and always using last row values
I used ForEach controller too but could not produce desired outcome
First of all, forget about Beanshell, since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language for scripting.
Second, if I correctly got your point and you want to iterate all the values, i.e. from 1 to 15, you need different approach, for example read the whole file into memory, split each line by comma and create a JMeter Variable for each "cell" value, example Groovy code would be something like:
SampleResult.setIgnore()
def lines = new File('load_test_date.csv').readLines()
def counter = 1
1.upto(lines.size() - 1, { index ->
def line = lines.get(index)
line.split(',').each { column ->
vars.put('value_' + counter, column)
counter++
}
})
if you execute the script and look into Debug Sampler output you will see the following JMeter Variables
In order to iterate the generated variables you can use ForEach Controller configured like:
And use ${value} in the HTTP Request sampler to access the next "cell" value on each iteration:

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

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

Jmeter Beanshell: Take multiple variables from CSV Data Set Config?

I have a Jmeter test in which I want to post an XML message to a JMS queue. This message will be formed dynamically via a BeanShell Preprocessor, which pulls data from multiple CSV Data Set Config elements.
One item of this XML message that is dynamic is the number of elements in it - it will be a random number between 1 and 10. For each Line element, I want to pull a different variable from a CSV Data Set Config element. However, I'm finding if I do something like the below, I keep getting the same variable:
for (int i = 0; i < numberOfLines; i++) {
InputXML = InputXML + "<OrderLine ItemID=\"${ItemID}\" />";
}
The above will keep using the same ${ItemID} variable for all of lines but what I want is for it to grab the next one in the CSV file.
Is there any way to accomplish this via Beanshell?
To go along with your data, if CSV looks like (first row will saved as variables)
0,1,2,3,4,5,6,7,8,9
a,b,c,d,e,f,g,h,i,j
The Beanshell will use index i to get value of column i in CSV:
String InputXML = "";
for (int i = 0; i < 10; i++) {
String a = vars.get(String.valueOf(i));
InputXML = InputXML + "<OrderLine ItemID=\"" + a + "\" />";
}
vars.put("InputXML",InputXML);
InputXML variable will hold the full value.
If you want random value until 10, you can use JMeter function ${__Random(0,10,myRandom)}.
If you want to get random line in CSV you can use the similar answer.

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.

In Jmeter bean shell preprocess is there any way to read the lines of CSV data file and put into an array

In Jmeter bean shell preprocess is there any way to read the lines of CSV data file and put into an array
csv file contains
data1
date2
date2
i want put all three values in to array and send to Http request in jmeter for for each controller
Thanks in Advance
If you want the Beanshell
BufferedReader reader = new BufferedReader(new FileReader("path.to.your.file.csv"));
int counter = 1;
for(String line; (line = reader.readLine()) != null; ) {
vars.put("date" + counter, line);
counter++;
}
However I don't see any value added by Beanshell here, it is recommended to avoid scripting and use JMeter components where possible. If you need to send values from CSV file consecutively I would recommend using one of the following test elements instead:
CSV Data Set Config
CSVRead or StringFromFile functions

Resources