Jmeter: Capturing of tokens (Say 50 tokens) from single request and pass one token at a time to the next upcoming 50 requests - jmeter

we have certain token mechanism recently implemented into our project. What it does is, say it generates 50 tokens while triggering the corresponding API. Now we have to capture this tokens and pass it sequentially one by one to the next 50 API’s request body. One way is by writing multiple json path extractors I have to capture this values individually and pass it to all the requests. But readability is not proper this way. Is there any other way to capture this tokens and pass it to all the next requests one each. Say capturing those into a file and passing it sequentially or something.
Sample Response from where tokens generated:
{
"data" : {
"requestTokens" : [ "9FDE794DD00E4A09122343BDCAF214E9", "616C5DFFC1234516A925824AEA6EFE9F", "7A8C507EC1DF4AD88E0912345E1DB409", "763C32CF67899946B6BC946949BD1344", "3C143F2FC25E495012345500E0F343DF", "3FD78335C763420B1234574061D9417F", "C43C368A1E612345AB17D2BA2693BEAF", "56E8FA9036D3486123451DE3237004DC", "5867B8E399FB4E12345626337D0E143C", "D06B30BDEAFC4A7D8618BF67712345DB", "F795258D390D4812345EB62C83BEFC58", "F0829D861234560392DE432E121B3CD4", "C8B9D5E6BE6A465FB91B0123459FBA9A", "4169D93D97204123457BA5A98C914D27", "784809E5BCBF4F123459D7D848AD67CE", "D0BFDCDC13994C0123455B2B110C35F9", "4F59619BBEDE4FE812345EA14C5E785", "E3942AE182214605BE91234595D95C18", "2005C506659C425EAD2022446123459B", "FE716E2A13A74C759C12345AED5AD54C" ]
}
}

Add JSON JMESPath Extractor as a child of the request which returns this JSON
Configure it as follows:
Add ForEach Controller after the request which returns this JSON
Configure it as follows:
Put your "next request" as a child of the ForEach Controller
Refer the token as ${token} in this request
That's it, ForEach Controller will loop as many times as there are tokens in the first response and each iteration the ${token} JMeter Variable will be updated with the new value
Demo:

Related

Use of Json extractor

Im running a test plan containing 10 requests i need to get the variable value from 3rd response json to be passed to request URL of 10 th request passed . any way we can use json extractor to do this?
This can be accomplished by using any of the post processors for correlation in amongst any of the requests. I have shown an example below with JSON Extractor
Request Sample
The value that I am going to extract from 3rd request's response is "I am the value to be fetched from 3rd response"
JSON Extractor
I am using the below syntax in JSON Path Expression to extract data from "valueToBeFetched" json object and storing it in variable named "extractedValue_C"
$..valueToBeFetched
10th Request
Replacing the extracted value with syntax ${extractedValue_C} in 10th request
Output
Response Captured from 3rd Response
Captured value passed in 10th request
Hope this helps!
JSON Extractor obeys JMeter Scoping Rules so if you put it as a child of the 3rd request - it will be applied to 3rd request only.
If you come up with a valid JSONPath matching the value you want to extract - the value will be saved into a JMeter Variable which can be used anywhere after 3rd request (where it is defined or overwritten in next iteration)

ForEach Controller won't run multiple HTTP Requests

I have a ForEach Controller that loops over an array of values which works. Inside the ForEach block I have two HTTP requests and one extractor.
ForEach Loop {
+ HTTP Request 1 (This uses attribute from ForEach)
+ Extractor
+ HTTP Request 2 (This uses attribute from Extractor)
}
The first HTTP request runs and the extractor as well but the second HTTP request fails to run.
I've checked the logs and nothing is mentioned about this HTTP Request. I also tried moving the Extractor out from under the HTTP Requestor 1 but that also doesn't work.
There is no problem to have multiple Samplers as ForEach Controller children
The possible reasons for not executing the 2nd HTTP Request are in:
Your extractor fails somewhere somehow, double check that the variable is set and has expected value using Debug Sampler and View Results Tree listener combination
Your 2nd HTTP Request configuration is not correct, i.e. invalid characters in "Server Name" field or unsupported protocol or the request is actually being executed but takes too long, etc. I would recommend looking into jmeter.log file as normally it has enough troubleshooting information

How to loop an HTTP request and update the variables each time in Jmeter BeanShell

I have 2 HTTP request: One to GET data from an api and the other to POST data to the api.
The GET request brings several users in JSON. The POST request requires to 1 request per user. Hence I need to:
Loop the same POST request several times depending on the number of users (already did this by using a while controller that checks the number of users from the JSON response).
For each POST request, I need the variables used in such request to be updated depending on the user's information inside the JSON response.
The approach I am attempting is to use BeanShell PreProcessor inside the POST request but I'm having troubles with it.
Suppose one variable is called ${name} in the request body of the POST. I am using a JSON Extractor PostProcessor (On the GET request) path: "Travelers[0].FirstName" that returns the first name of the first user but then I need the second user's name (Travelers1.FirstName) to be assigned to the same variable ${name} before the POST request is sent and so on with every single user.
I want to make a for loop like this:
for (int i = 0; i <= numberOfTravelers; i++) {
vars.put("Name", Travelers[i].FirstName)
}
The problem is that I do not know how to call a JSON path from a JSON response of another previous request. Is there a way to reference the jsonpath to the specific JSON response or a way to save the whole JSON response in a variable and then find the specific value inside that variable as a JSON path.
I have tried this with the JSON extractor but the problem is that if I use the path: Travelers[*].FirstName, it will actually get all the names on the JSON but the variable ${name} will only store ONE name, not all of them as an array that I can later access in my for loop with a normal variable ${name[i]}. That is why I need to access the JSON path from the BeanSheall.
Here a sample of the JSON response:
{
"Travelers":
[
{
"FirstName":"VICTOR",
"Surname":"ORREGO",
"Key":"1.1",
"PassengerRPH":1,
"TypeCode":"ADT"
},
{
"FirstName":"JULIO",
"Surname":"OZAETA",
"Key":"2.2",
"PassengerRPH":2,
"TypeCode":"ADT"
}
]
}
This is the PostProcesor JSON Extractor at the GET request that I'm using. it is currently assigning the first name it gets from the JSON response (Victor) to the variable ${Name}
I need that in the next iteration (of the POST Request) the variable ${Name} to return the next name in that path, which is Julio.
here is the solution..
Add a JSON Extractor to the get request .. use match no -1 to store all Firstnames as show below.
i'm extracting all Firstnames and storing it in JMeter variables with a single JSON extractor
2. To the same get request add a JSR223 Post processor and set the counter value to 1
vars.put("counter","1");
Add a while loop to the test plan and add the following condition to the while loop.
${__javaScript(parseInt(${counter})<=parseInt(vars.get("FirstName_matchNr")),)}
4.To the post request add a JSR223 Pre Processor and add the following code
vars.put("name",vars.get("FirstName_"+vars.get("counter")));
This will store FirstName_Matchno's value in name variable.
Add a JSR223 Post Processor to the POST Request and increment the counter.
int counter = Integer.parseInt(vars.get("counter")) +1;
vars.put("counter",Integer.toString(counter));
You can see in the results its substituting a different name on each iteration of loop
Let me know if it helps..

Beanshell code to call an API, parse JSON response

I am trying to implement a logic where i do not want to send HTTP Requests unless an API returns 0 for a field. If i send the requests without monitoring response from this API, my test is invalid. API returns response in JSON, i can parse and extract the data i need to compare. Below is my test structure.
Thread Group
* While Controller
* CSV Data Set Config
* HTTP Request
* JSON Path Extractor
* Constant Throughput Timer
* While Controller Condition: ${__BeanShell(source("function.bsh”))} != “0”
I want to call this API after every 5 minutes and proceed with sending HTTP Requests when field value is 0. I don't want to check before every HTTP Request just once before sending the first request.
Can someone please help me with the beanshell code (function.bsh) to get API response and parse json response ? Was implemented using python as below
max_behind = 0
response = requests.get("https://api")
consumers = response.json().get("consumers")
for total_behind in consumers.iteritems():
max_behind += total_behind[1].get("total_behind")
As Jmeter developers suggested "Better to avoid scripting languages in Jmeter". So in your case use "If Controller" to resolve your blocker. Below are the details
Use regular expression to extract the "API return field" value, once you hold this value in a variable "valueIs". As shown in belo image
Use "If controller " and in condition enter the following value "${valueIs}==1", then add child requests ( next API call/calls) to "If controller". As shown below image

How to Handle Dynamic Requests in JMeter - Which may/may not occur with each run

In Web Application :
There is Single Page having Different Sections/Partitions
Each section Retrieves the Data with the Help of Filter Query.
If there is no matching Result, Section will Send below Request only :
Request 1: domain/search/jobs/csuser__search2_1413357426.1559
If the Query returns any matching Result, Section will Send below Two Requests:
Request 1: domain/search/jobs/csuser__search2_1413357426.1559
Request 2: domain/search/jobs/csuser__search2_1413357426.1559/results_preview
How can I manage Request 2, which may or may not occur with each run.
Currently I am manually Recording entire Network calls, Removing unnecessary ones & running it for 'N' Loop Count. How can I make sure while test is runing if any section has matching results Request 2 Should also be taken care which I might not have benn recorded on my first execution.
You can use combination of Beanshell PostProcessor and If Controller to work it around as follows:
Add a Beanshell PostProcessor as a child of the Query request
Put the following code into the PostProcessor's "Script" area:
int length = prev.getSubResults().length;
if (length > 1) {
String path = prev.getSubResults()[length - 1].getURL().getPath();
if (path.contains("results_preview")) {
vars.put("resultPresent", "true");
}
} else {
vars.put("resultPresent", "false");
}
Add an If Controller after the request
Depending on your scenario put on of the following conditions to If Controller's "Condition" input
${resultPresent}==true - children will be executed if the query returns results
${resultPresent}==false - children will be executed if the query doesn't return anything matching
Beanshell code does the following:
check how many requests were executed
if there were more than 1 requests, path of the last request is extracted
if path contains "results_preview" variable resultPresent is being set with the value of "true"
if there was only 1 request then resultPresent variable is false
References:
How to use BeanShell: JMeter's favorite built-in component
JMeter “if controller” with parameters
SampleResult class JavaDoc
As Dimitri said. The processor should run after (post) request 1. The if controller will then act on the results of the processor. Section two is only run when the condition is not "false".

Resources