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

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

Related

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

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:

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)

How to store entire encrypted response, unencrypt it with POST method and update the response for next rest call using Jmeter

Run Get method to get the data of the policy - response is encrypted.
Run a Post method to decrypt the response from step 1
On the response from Step 2 there is the field policyStatus and will be changed to value = 2
Encrypt the decrypted payload with changes in the policyStatus. I created a regular expression extractor in step 2 to get the response, but the problem is if I directly parameterized it in this step I wont be able to change the value of policyStatus, is there a way to change the value after extracting without posting it so that I can encrypt it and then post it.
I tried the __strReplace() function but this will be possible if the request is step 4 is not parameterized. see below
Actual Body(Parameterized):
{
"isEncrypt": true,
"payload": "{${payload}}"
}
Body(Not Parameterized):
{
"isEncrypt": true,
"payload": "{\"policyNumber\":\"\",\"policyStatus\":\"1\",\"ownerName\":\"\",\"exchangeRate\":1,\"product\":{\"productName\":\"",\"category\":\"T\",\"shariaIndicator\":\"",\"currency\":\""},\"billings\":[{\"type\":\"",\"amount\":0,\"currency\":\""},{\"type\":\"",\"paidToDate\":\"2019-07-08\",\"mode\":\"",\"amount\":,\"currency\":\"",\"minimumPayment\":,\"outstandingPeriod\":0,\"paymentSuspend\":}]}"
}
the policyStatus is inside the payload field which comes from the response on step 2.
tried the advice from this --> How to store entire response and update it for next rest call using Jmeter
but this applies in the value of the single field.
Add JSR223 PostProcessor after the Regular Expression Extractor in step 2
Put the following code into "Script" area:
vars.put('changedPolicy', vars.get('myVar').replace("\\\"policyStatus\\\":\\\"1\\\"","\\\"policyStatus\\\":\\\"2\\\""))
Replace myVar with your actual JMeter Variable reference name from the Regular Expression Extractor
That's it, the JSR223 PostProcessor will generate changedPolicy variable with the policyStatus value set to 2
Demo:
vars keyword used in the Groovy script is the shorthand for JMeterVariables class instance, it is used for reading myVar variable value and writing the replacement into changedPolicy variable. See Top 8 JMeter Java Classes You Should Be Using with Groovy to learn more about JMeter API shorthands available for Groovy scripts.

Extracting value from jmeter post request

I want to extract value of the parameter sent through post request in jmeter.
I know the use of regular expression for extracting response value or request URL but here I would like to extract the value of post request.
I've been thorough how to extract value from request in Jmeter but it didn't worked.
Not sure why do you need it as given you sending "something" you should already have that "something" hence you don't need to extract it, however here you go:
In order to save 1st parameter value (or the whole post data if you use "Body Data" mode):
Add Beanshell PostProcessor as a child of the HTTP Request.
Put the following code into the PostProcessor's "Script" area:
String request = ctx.getCurrentSampler().getArguments().getArgument(0).getValue();
vars.put("request", request);
You will be able to access extracted value as ${request} where required.
Clarifications:
ctx - shorthand for JMeterContext class instance
getCurrentSampler() - in case of HTTP Request sampler stands for HTTPSamplerProxy
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for more information on using JMeter and Java API from Beanshell test elements in your JMeter test.
I added a Beanshell PostProcessor in my http request with following code.
import org.apache.jmeter.config.Argument;
import org.apache.jmeter.config.Arguments;
Arguments argz = ctx.getCurrentSampler().getArguments();
for (int i = 0; i < argz.getArgumentCount(); i++) {
Argument arg = argz.getArgument(i);
String a = arg.getValue();
vars.put("EMAIL",a);
}
Explanation: I get a my request as a json and put it in EMAIL. Now I can use EMAIL as a variable in my other request.
Then, I added a jp#gc Json Path Extractor and I applied it to a Jmeter Varaible.
Now, Email will be used as variable, which contains my json request and I can extract using jsonPath Extractor.
An easy way to do this is using the JSON Path Extractor.
There are just
For the example you gave
{ "data" : { "name" : "john_doe", } }
'Variable Name: YourNewVar'
'JSON Path: $.data.name'
Should work, but you may need to do some experimenting.
You may want to add a "debug sampler" (its one of the standard samplers) and put in its title $YourNewVar so you can see what is being extracted.
Beanshell and "Regular Expression Extractor" will work, of course, but may be a little harder to use if you are not familiar with them.

JMeter - JSON Extractor post-processor

I've been trying to figure out how to configure a simple JSON Path extractor (provided on jmeter-plugins) and where to put it (inside an Http sample, outside...)
As you can see, ${expiredaccesstokenerror} is empty.
In order to fill this variable, I'm trying to extract a vallue from body response:
As you can see I'm trying to extract from json body content like:
{
"error_description":"Access token expired",
"suberror":"expired_accesstoken",
"error":"invalid_grant"
}
So, I've set JSON extractor for extracting $.suberror, however, it's always empty.
${expiredaccesstokenerror} in sampler is trying to get variable before request or response. In post processor you set the variable expiredaccesstokenerror but it's too late for displaying.

Resources