How to store values from a while loop to a list as a property in JMeter - jmeter

Is there a way to add each session Id that is retrieved from a Loop Controller to a list and assign it to a property for use in the following thread group? Below I used a couple of Dummy Sampler to explain my requirement.
I had 3 users stored in a list to retrieve 3 session ids in the setUp Thread Group.
JSR223 PreProcessor
List usernames = Arrays.asList('Peter', 'Alex', 'Mary');
props.put('accounts', usernames);
I was able to read a username from this property to get a session id in the response accordingly per iteration in the Loop Controller.
"sessionId": "this_is_my_session_id-${__groovy(props.get('accounts').get(${__jm__LoopController__idx} % 3),)}-${__jm__LoopController__idx} "
I parsed the 3 session ids out by a JSR223 PostProcessor
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper();
def response = jsonSlurper.parseText(prev.getResponseDataAsString());
def json = JsonOutput.toJson(response.sessionId)
def sessionId = new JsonSlurper().parseText(json)
log.info('The session id is:' + sessionId)
ArrayList<String> sessionIds = new ArrayList<String>();
props.put("sessionIds", sessionIds.add(sessionId))
I needed to add these 3 session ids to a list and assign it to a property so that I can use one session id inside the property per VU/thread in the following Thread Group. But it didn't work as expected. It threw error saying No such property: sessionIds
${__groovy(props.get(sessionIds).get(${__jm__UseSession__idx} % 3),)}

We don't know what do you "expect"
Most probably the problem is here:
props.put("sessionIds", sessionIds.add(sessionId))
Collection.add() function returns a boolean value so it puts true to the sessionIds property instead of the real value of the ArrayList.
So I believe you need to change it to something like:
sessionIds.add(sessionId)
props.put("sessionIds", sessionIds)
if you're going to run the JSR223 Test Element in the loop you can also reconsider the way you're initializing the sessionIds and implement the following logic:
If sessionIds property exists - read its value
If it doesn't exist - create a new ArrayList
Something like:
ArrayList<String> sessionIds = props.get("sessionIds") ?: new ArrayList<String>()
More information on Groovy scripting in JMeter: Apache Groovy: What Is Groovy Used For?

Related

Unable to access UDV variable

in below script i am trying to access user defined variable and modify the data and passing the value to post data using the variable "data".But after modifying the data it is not being sent to http request.
String temp = vars.get("${json}"); //access UDV data
temp = temp.replaceAll("__"," ");
vars.put("data",temp); //pass the data to another udv "data"
Please let me know whether there is any mistake in my above script
If you have an User Defined Variable called json which is created like:
then you need to change your code like:
String temp = vars.get("json")
or alternatively use "Parameters" section of the JSR223 Test Element:
you are accessing the variable incorrectly
String temp = vars.get("${json}"); //access UDV data is wrong
String temp = vars.get("json"); //access UDV data
refer here for more details

How to extract value from Jmeter get property and save as variables. These values will be used in api call

getproperty values passed from Thread Group 1 to Thread group2
Result from BeanShell assertion
Step 1- USing jdbc request to get data from database with 2 columns and multiple rows.
Step 2 - From ThreadGroup 1, Set property to the database results using ${__setProperty(StateCodeProperty,${stateDetails})};
Step 3 - Access in Thread Group 2 by get property using beanshell assertion- String result = (vars.get("${__property(StateCodeProperty)}")); I need help on how to separate the columns and use it in api call. –
In any case if you want to access the DB results in different Thread group then you can try to do something like this inside beanshell assertion (not sure though) -
ArrayList results = ${__property(StateCodeProperty)}; //it should return the object as an arraylist
for (int i; i < results.size(); i++) {
if (results.get(i).get("statecode").equals("NY")) { //iterating the results, 'statecode' is the name of your 1st column, similarly you can do for 'State'
//Do your comparisons or whatever you like here
}
}

Execute request for each element in CSV, not per user

I'm using jMeter 3.2 to write some tests. I have a CSV file with test account info. Each row contains login info for a user. Each user needs to request a token that is used on later requests.
My test plan:
The get token request retrieves a token. The login requests logs in the user and returns another token. Select customer card selects a customer and returns the final token. The code for the postprocesser is (I'm not experienced in this, so any advice is appreciated):
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
// Check if our map already exists
if (props.get("map") == null) {
JSONObject obj = new JSONObject();
obj.put("${department}", new String(data));
log.info("Adding department to map. Department: ${department}. Token: " + new String(data));
props.put("map", obj.toJSONString());
} else {
// Retrieve the current map
map = props.get("map");
JSONParser parser = new JSONParser();
JSONObject jobj = (JSONObject) parser.parse(map);
// Add the new department (with it's token) to the map
jobj.put("${department}", new String(data));
log.info("Updating map for department. Department: ${department}. Token: " + new String(data));
props.put("map", jobj.toJSONString());
}
Attempt 1:
I'm setting up a once only controller to log in a user and retrieve the token.
Now lets say I have 10 lines in my CSV file but in my test I only want to use 3 users and loop 10 times. What happens is that 3 login requests are sent (one for each user). This works fine for the first iteration. At the 2. iteration the 3 threads will use row 4-6 which doesn't have a token and thereby fail.
Attempt 2:
I'm using an if controller to check whether the token has been set or not. I haven't got this working at all. I added a beanshell preprocessor to the controller where I attempt to retrieve the token. If it's null or empty I set the token variable to "". In the if controller I check for this value. But yeah. No luck yet.
Attempt 3
In Beanshell check if the token is created already. If not, call the test fragment that retrieves it. Unfortunately this seems not possible.
It might be worth noting that I store my tokens in a property, so that all threads can access it.
Please let me know if you need more information.
I figured out a solution. In essence what I tried to do is to store a token for each row in the data file.
I did this by creating a setUp Thread Group which is executed before other thread groups. In this I loop through the data and store a token for each. Now all other thread groups may access these as they run.

How to send "empty" variable into JMeter

I have some functional tests created via JMeter. It is pretty huge but i can't handle one simple check.
I generate properties using BSF pre processor with help of JS. Parameter (lets call it "payment_fee") should be generated only if other parameter (lets call it "role") has a value = 1 .In this case we post pre generated integer into payment_fee and everything works well. But if role =2 then we should post nothing into payment_fee.
The problem is, i don't know how to say to JMeter: In case if role = 1 use variable with pre generated payment_fee but if role = 2, you shouldn't use this variable so just post an empty value for payment_fee . Server waits for an integer so empty string or NULL had been rejected.
For more clarification:
I will try to explain more clear.
Here is a part of my code
var role = Math.floor(Math.random()*3+1)
var paymentType = ["creditcard","cash"]
var randomPay = installerType[Math.floor(Math.random()*installerType.length)];
var payment = "";
var paymentFee;
if (role == 1){
payment+=randomPay,
paymentFee = Math.floor((Math.random() * 999) + 1) / 10.00
}
vars.put("role", role);
vars.put("payment", payment);
vars.put("paymentFee", paymentFee);
And if role == 1 i should post paymentFee value. Like this - http://prntscr.com/b50kk1 BUT! if role == 2 || role == 3 I should remove this value, so it should be like this http://prnt.sc/b50l82
I don't fully understand what you're trying to do as your 2 statements clash:
But if role =2 then we should post nothing into payment_fee
Server waits for an integer so empty string or NULL had been rejected
You should know few bits about JMeter properties:
Properties are global for the whole JVM. Once you set property it will "live" until you exit JMeter.
Properties can be accesses by all threads of all Thread Groups.
So it might be the case when you define property earlier or by another thread and expect it to be not set later on.
Also BSF PreProcessor and JavaScript isn't the best combination from performance perspective, consider switching to JSR223 PreProcessor and Groovy language.

Passing values to parameters in Jmeter

Suppose I have a variable in the RequestParameter as StudentList list where StudentList is a class as follows:
class StudentList
{
List<Students> stud=new ArrayList<Students>();
}
and Students is a class having fields firstName,lastName etc.How to pass values to the list variable in Jmeter as a request parameter?
You can pass values to the list variable in Jmeter via CSV Data Set Config. Where you have to create first .CSV file with values and set the parameters in the HTTP request. Below are shared steps with screenshots of results.
Create an HTTP request under the Thread group and change the name to "Student"
Select CSV Data Set Config from Config Element under the same Thread Group
Create .CSV file with values related firstname and lastname and set the loop count in the Thread Group as 3 as there are 3 records available in CSV file
CSV File
Set Path in CSV Data Set Config under Filename and Set the variable name as
"firstname,lastname"
CSV Dat Set Config
Set the parameter in value with the $ sign as per the attached screenshot.
Request Parameter
Select View Result Tree from Listener under the same Thread Group
Save the Test plan and Run or Start.
Under the view result tree, when clicking on each request you will find firstname and last name under each request parameter.
Student 1
Student 2
Student 3

Resources