How to setup nested ForEach Controller and send sub-request on JMeter - jmeter

I have 3 types of request,
request 1: www.test.com/data
will return data in JSON Array
request 2: www.test.com/img/{img_id}
{img_id} comes from items return by request 1, and requst 2 will return an {uid}
request 3: www.test.com/test/{uid}
I use jmeter to test this flow, now I was able to send request 1 and
then use ForEach Controller to send some request 2, but I don't how to send request 3 according to the response of each request 2
I'm newbie to JMeter , Is anyone could help , Thanks

You need to add one more ForEach Controller nested in the previous one.
So your Test Plan structure will be looks like:
Thread Group
Request 1
RegExpExtractor 1
ForEach Controller 1
Request 2
RegExpExtractor 2
ForEach Controller 2
Request 3
You may use Regular Expression Extractor with -1 as a Match No. parameter to use it in ForEach Controller (from RegExpExtractor 1 to ForEach Controller 1 and from RegExpExtractor 2 to ForEach Controller 2).
Check this Test Plan as an example.

Related

How to add parameters to a HttpRequest programatically in JMeter

I use JMeter in our product performance testing now.
I have a performace test scenario below:
Exract 1000 unique IDs from a request A.
Add the 1000 unique IDs to next request B as "form parameters". check the request B response time.
The request B is like:
Method: Post
URL: http://www.aaa.com/abc/def
Form parameters:
para1 : value1
para2 : value2
ID : ID1
ID : ID2
ID : ID3
......
ID : ID1000
I know this request isn't a Canonical usage of http request. but it is used in our product for years.
Now I get the 1000 unique IDs from request A with the help of "regular expression extractor",
My question is:
how to pass the variables to request B, and set the 1000 IDs as "form parameters" of request B?
Add JSR223 PreProcessor as a child of the HTTP Request sampler where you need to add 1000 parameters
Put the following code into "Script" area:
def data = new org.apache.jmeter.config.Arguments()
1.upto(vars.get('ID_matchNr') as int, index -> {
def parameter = new org.apache.jmeter.protocol.http.util.HTTPArgument('ID', vars.get('ID_' + index))
data.addArgument(parameter)
})
sampler.setArguments(data)
That's it, the JSR223 PreProcessor will read all the JMeter Variables which start with ID_1 and ending with ID_XXXX and add a corresponding parameter to the HTTP Request sampler
More information on Groovy scripting in JMeter context: Apache Groovy - Why and How You Should Use It

How to iterate the foreach loop in JMeter

I got the array response from the one API and I passed to the response to the other API.
For example:
Response from one API is {status:200,data:{name:"Manikyam", selected_products:[1,2,3,4,5]}
I need to iterate the selected_products from the response using foreach or other loop which is suitable of this.
Iterations like:
http://dummy.com/product/1
http://dummy.com/product/2
http://dummy.com/product/3
http://dummy.com/product/4
http://dummy.com/product/5
I tried some ways like using forEach but I haven't any luck.
The below answer assumes that your response is a valid JSON looking like:
{
"status": 200,
"data": {
"name": "Manikyam",
"selected_products": [ 1, 2, 3, 4, 5 ]
}
}
Add JSON Extractor as a child of the request which returns the above JSON and configure it as follows:
Names of created variables: anything meaningful, i.e. product
JSON Path Expressions: $.data.selected_products.*
Match No: -1
Add ForEach Controller and configure it as follows:
Input variable prefix: product
Output variable name: product
That's it, if you add a Sampler as a child of the ForEach Controller, the controller will iterate all the variables so you will be able to refer each and every as ${product} where required like http://dummy.com/product/${product}
Demo:

Jmeter : How to get first userID from first request and transfer to second request same userId?

I have a script include two HTTP request
1 The first request is User Authentication。include userId.....
2: the second request also includes userId.
The two parameters are consistent。
How to get the first userID from the first request and transfer to second request same userId?
I want to get userID from the first request, not from the response, response body does not include userId, transfer the same userId to the second request.
Here is the first request body:
[
{"productId":"5551",
"userId":"${__RandomString(32,44e00d674dee4ff7a2d4f0081991b6d40Bs9Hc)}",
"service":"200008",
"app_system":"7.1.1",
"equipmentId":"866935038314977",
"app_devicetype":"vivo X20A",
"app_platform":"Android",
"app_version":"3.1.3",
"market":"icash_main"}
]
Use Extractors for the co-relating your requests and responses.
First, you need to extract the userID from the response of your 1st requests.
To do this, choose an extractor (Use JSON Extractor if your requests return the JSON response) and add to your 1st request.
Second, After getting the value of userId through a variable using the extractor, you can use it in your subsequent requests.
Edit:
As you want to use the same userId in both requests, use User Defined Variables in your test plan and add a variable userID in it like this:
In your request body use the variable of userId like this:
{"productId":"5551",
"userId":"${userId}",
"service":"200008",
"app_system":"7.1.1",
"equipmentId":"866935038314977",
"app_devicetype":"vivo X20A",
"app_platform":"Android",
"app_version":"3.1.3",
"market":"icash_main"}
Here is the requests body of the two requests which are using the same userId
Body of the Request 1:
Body of the Request 2:

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
}
}

JMeter: Dividing dataset between 'users'

I have a Dataset, obtained from a DataBase query, of about 5,000 elements. I would like to divide this data into chunks and then have the 'users' (threads) make a HTTP request.
The purpose of this is we have a site that gives realtime information on transient data, I want to simulate multiple concurrent requests against the service.
1 - Tried to create a test plan where the DB query was done and then processed via a HTTP request via a ForEach controller. This works fine when I have only 1 'user', however; if I increase the user count to 2+ then the DB query is run 2+ times and each 'user' runs through the entire 5,000+ data points
2 - I tried moving the DB query into it's own Thread Group and then using BeanShell to put the data into the environment (props.add(...)). This worked in that the data was there but again each 'user' in the http request Thread Group iterated all the data.
Ideally what I would like is to take the data, and have the HTTP Request Thread Group divide the data so that Thread 1 takes the first 2,500 and that Thread 2 takes the second 2,500 (or if there are 4 'users' then thread 1 takes the first 1,250, thread 2 the next 1,250 and so on).
I just started looking at JMeter and I don't think it can do this "automatically" but I wanted to ask in case I'm missing something obvious.
Put a Counter element to testplan with:
Starting value: 1
Increment: 1
Reference name: (for example) cid
and disabled "Track counter independently ...".
Then add JSR223 or BeanShell sampler and write a simple code:
Integer cid = Integer.valueOf(vars.get("cid"));
Integer dataShift = 2500;
Integer startReadDataFrom = (cid - 1) * 2500;
vars.put('startReadDataFrom', String.valueOf(startReadDataFrom));
Then you can use variable ${startReadDataFrom} as a starting point to read data for every thread (0, 2500, 5000, 7500, ...).
The fastest and the easiest way is to store the data from the database into a CSV file, once done you should be able to use CSV Data Set Config and its Sharing Mode feature according to your requirements.
The storing of the data could be done as follows:
Define Result variable name in your JDBC Request Sampler:
Add JSR223 PostProcessor as a child of the JDBC Request sampler
Put the following code into "Script" area:
resultSet = vars.getObject("resultSet")
result = new StringBuilder()
for (Object row : resultSet ) {
iter = row.entrySet().iterator()
while (iter.hasNext()) {
pair = iter.next()
result.append(pair.getValue())
result.append(",")
}
result.append(System.getProperty("line.separator"))
}
org.apache.commons.io.FileUtils.writeStringToFile(new File("data.csv"), result.toString(), "UTF-8")
Once execution will be finished you should see data.csv file in "bin" folder of your JMeter installation containing the data from the database

Resources