Variables in httprequest post body - jmeter

I'm trying to generate a jmeter script where a unique folder is created each time the script is run - adding a variable of some sort to the folder name, such as a username+timestamp, should be enough to guarantee uniqueness. However, jmeter is not resolving the variable to its value - although it is when the variable is read out of a csv file (which isn't suitable).
Basically, I'm editing the PostBody in the http request, as follows:
{"alf_destination":"workspace://SpacesStore/90368635-78a1-4dc5-be9e-33458f09c3f6","prop_cm_name":"Test
Folder - ${variable}","prop_cm_title":"Test
Folder","prop_cm_description":"Test Folder"}
where variable is basically any variable I've tried so far (such as a random string, timestamp, etc.)
Can anyone suggest how to get the variable resolved?

You can use jmeter (since 2.9 version) uuid feature -> http://jmeter.apache.org/usermanual/functions.html#__UUID
${__UUID}
and
1) If you want just 1 value for the whole test, add a "User Defined
Variables" Config Element to your test. This will be evaluated when
you load the test script the first time.
2) If you want to have the value change for every thread execution,
but stay the same during each thread instance: under your 'Thread
Group', add a 'Pre Processors -> User Parameters' to your thread group
- and add the variable there.
Also, if you want the value to change each time the thread starts over
(each 'iteration' of the script within the thread group), you can
check the "Update Once Per Iteration" box on the User Parameters - and
it will get a new value each time it starts the thread over at the
beginning of th test script (within that thread group).
http://mail-archives.apache.org/mod_mbox/jmeter-user/201208.mbox/%3C004301cd853e$0c4a60c0$24df2240$#gmail.com%3E

With JMeter 2.9, the following works:
In HTTP Request Sampler, Tab "Post Body" add for example your JSON data and include the variables in it:
{"uuid":"${new-uuid}"}
new-uuid is a user defined variable.
This will send (from View Results Tree, Tab "Request"/"Raw"):
POST data:
{"uuid":"a1b2c3d4e5f6"}

I did this by referencing a variable in the http request post body - ${formvalues} - created using a beanshell preprocessor which is appended to the http request sampler. Beanshell contents:
double random = Math.random();
String formvalues ="{\"alf_destination\":\"workspace://SpacesStore/90368635-78a1-4dc5-be9e-33458f09c3f6\",\"prop_cm_name\":\"Test Folder - ${uname}_" + random + "\",\"prop_cm_title\":\"Test Folder\",\"prop_cm_description\":\"Test Folder\"}";
vars.put("formvalues",formvalues);
So this creates a folder with the username (${uname}, taken from the csv) plus a random number - it's crude as there could potentially still be cases where the script tries to create a folder with the same name as an existing one, but it will work for my case.

suppose you have the value "NewYork" in jmeter variable "Location".
Use it like this in HTTP POST BODY DATA:
{location:"${Location}"} => which gets interpreted as {location:"NewYork"}

Related

JMeter JSON Path extractor

I use JMeter 4, I have a problem in a JMeter JSON Path Extractor.
I have done an HTTP Request (POST) to a service that I wan't to test.
Response data from the service is
{"rid":"661ff2d7-12e8-e811-8110-00215a9b9851",
"participation":{"rid":"ed8cfced-0063-4fda-92fd-b23f50197797"}}
I wan't to extract the first GUID witch is allocated to the first rid.
As JSONPath Expression I have used $.rid and wan't to assign that value to a JMeter variable. Therefore I have checked the radio button JMeter variable and entered my JMeter variable which is int_rid.
When I execute my JMeter testplan the int_rid variable will be null.
In JSON Extractor If you check the radio button JMeter variable it expect to search inside the contents of JMeter variable, which you don't want, usually Main sample only is enough
Main sample only - only applies to the main sample
Sub-samples only - only applies to the sub-samples
Main sample and sub-samples - applies to both.
JMeter Variable Name to use - assertion is to be applied to the contents of the named variable
Put int_rid in Names of created variables field and chose Match No. 1 to find the first value

Automate sending a request and saving the response

There is a URL which I want to hit and save the response. The URL id needs to be incremented each time and save the response. For example -
First Get Request - http://google.com/getdata/?Id=1
First Response - one
Second Request - http://google.com/getdata/?Id=2
Second Response - two
and so on...
I want to hit the request with increment the id each time and save the response
I have tried using fiddler but unable to figure how to increment the id and save the response.
P.S. - I have to make around 6,00,000 hits
Since the 'Postman' tag is mentioned, I can help you regarding how to implement this in Postman.
Postman has a nice feature of using 'variables'.
You can use environment variables or globals.
Read more about these on their docs:
https://www.getpostman.com/docs/v6/postman/environments_and_globals/variables
You can use a global variable such as 'counter' and set it to 1 / whatever starting point you want.
Then you can modify your request like so :
http://google.com/getdata/?Id={{iteration}}
Now, in the Tests script of the request you can write the following script
let i = parseInt(pm.globals.get('iteration')) + 1;
pm.globals.set('iteration', i);
Also, to access the response you can use the following command in Test script:
console.log(pm.response); // Use pm.response as per your needs
Save the request in a collection.
Now load the Postman's Runner and select the collection.
Now you can put an iteration count of 6,00,000 and hit run!
Remember, heavy iterations will cause performance degradation.
In JMeter you need to click , Ctrl+0 and Ctrl+1 to create , Thread Group and HTTP Request
In Thread Group put the number of hits you need in Number of Threads (users)
In HTTP Request Put in Server Name or IP www.google.com and in Path /getdata/?Id=${__threadNum}
__threadNum will create increasing number from thread 1 to number of hits.
For small number of hits or debugging you can add View Results Tree to view request/response by clicking Ctrl+9 in Test Plan/Thread Group level.
To save the response use Post Processor, especially by adding Regular Expression Extractor below HTTP Request by clicking Ctrl+2.
Allows the user to extract values from a server response using a Perl-type regular expression. As a post-processor, this element will execute after each Sample request in its scope, applying the regular expression, extracting the requested values, generate the template string, and store the result into the given variable name.
Import to notice that for load testing you need to work with non GUI mode, which means call jmeter using command line as jmeter -n -t myTest.jmx
you will use Command-line mode (called Non-GUI mode) to run it for the Load Test.
Don't run load test using GUI mode !
For saving all responses to a one file see save response data or if you want to save file per thread/user you can add Save Responses to a file
Fiddler:
Open script editor (Control + r ) then add the following code inside OnBeforeResponse
static function OnBeforeResponse(oSession: Session) {
if(oSession.oRequest["X-SAVE-ME"] != "")
{
oSession.SaveResponseBody("C:\\tempfiddler\\" + oSession.SuggestedFilename);
}
}
Go to the "Composer" tab and include the header X-SAVE-ME with any value, in the URL, replace your ID with # (just like this: http://google.com/getdata/?Id=#) fiddler will now ask for the starting and ending value of ID before executing;
Please find the snapshot below for your scenario.
Scenario_Testplan
First, go to user properties and put "sample_variables = ID, Response_File_Name" or whatever the name you choose for the variables. Restart jmeter.
Create the below plan:-
CSV data set config to have incremental values and response file name
HTTP request will use ${ID}
Save response to a file will use ${Response_File_Name}
Hope this will help.
I would do this by command line, using a while loop with a curl to the URL, storing the body result on the standard output to a file. It would look something like this:
for i in {1..600000}; do curl "http://google.com/getdata/?id=$i" > body-result-id-$i; done
I couldn't test the line above because I don't have any access to a console right now, but I think it should work.
In Burp you can do this using the Intruder tool. First, capture a sample request in Burp. If you're unsure how to do this, please consult the getting started documentation.
Then right-click the request and selected "Send to Intruder".
In the Positions tab within Intruder, first click "Clear" then select the section you want to vary, and click "Add"
In the Payloads tab select the Payload type as "Numbers" and configure the range.
Click "Start attack"
For more information, consult the documentation.
One Another solution is that you can use Counter in jmeter. That you can find from below path
Thread Group > configElement > Counter.
Configure the Counter as per your need.
Give the Reference Name i for counter.
Use the variable in your request
For more information.

How to save values from HTTP response with JMeter?

on a JMeter test plan, I have too many HTTP requests. One of these creates a new session every time when clicking the create button.
How do I store that session_id in a CSV file for further operation?
Given you have already extracted this session_id using the relevant JMeter PostProcessor you can save its value into a file using JSR223 PostProcessor and the code like:
new File('/path/to/your/file.csv') << vars.get('session_id') << System.getProperty('line.separator')
Make sure you select groovy in the "Language" dropdown and tick Cache compiled script if available box.
If ${session_id} variable exists - JMeter will store its value(s) in the file provided.
There are a few ways to do it. The most useful is RegExp post processor.
It could be found here as it is shown in the following image.
Place it under Request that returns needed data in response.
The RegExp catches groups and stores them under different variable names, based on Name of Create Variable. The values could be searched in different areas of Response, as it is demonstrated in the image, we can search in headers, redirected pages, main bodies and so on. The Stored variable could be re-used in other HTTP Requests or processors (Post and Pre) through ${VariableName} (e.g. ${JSESSION_ID})
Reference name
RegExp itself
Capturing group
Match number
A default value to set if RegExp didn't work
DEBUG:
If a value is not found, the DEBUG in cooperation with Tree Results Viewer can help. Here they are :
The general script structure might look like :
Add BeanShell PostProcessor. Copy, paste the below code (with your modifications for path and var).
var = vars.get("your_variable_name");
FileWriter fstream = new FileWriter("/your/desired/path/results.csv", true);
BufferedWriter out = new BufferedWriter(fstream);
out.write(var);
out.write(System.getProperty("line.separator"));
out.close();
fstream.close();

Compare extracted variable across threads in JMeter

My goal is to POST to some URL from every thread in my thread group, which will create an asset somewhere. If all goes right, the first request will create the asset, then subsequent requests will see that the asset is already created (or in the process of being created), and will reuse that same asset.
The test plan:
Create N threads
HTTP Request - POST to some URL
Regular Expression Extractor - extract part of the response (the assetId generated by the POST request)
Verify that every thread extracted the same string from the response
My question:
What I don't have a clue how to do is the last step - verify that the value extracted from each thread is the same. How can this be done in JMeter?
To achieve your requirement, we need to share the value among all the threads.
Properties:
We can use properties to share a value. Lets assume a prop 'shared' is created with default value as blank "". Add the below code in the beanshell assertion. If it is blank, then a thread will add the value extracted from the RegEx. All other threads will just compare the value and if it does not match, it will fail it.
if(props.get("shared")==""){
props.put("shared") = "extracted";
}else{
if(!props.get("shared").equals("extracted")){
Failure = true;
}
}
Bsh.shared:
We can use the bsh.shared shared namespace to share the value among the threads and compare if the all the threads have the same value.
1.setup threadgroup will contain beanshell code like this to create a hashset.
import java.util.*;
if (bsh.shared.hashSet == void){
bsh.shared.hashSet=new HashSet();
}
bsh.shared.hashSet.clear();
2.The regular thread group will contain the code for extracting the value. Once the value is extracted, add it to the hashset which stores only the unique values. Any duplicate values are simply ignored.
bsh.shared.hashSet.add("value extracted");
3.teardown threadgroup will group will check the hashset for the size. If the size is more than 1, then it failed.
log.info(String.valueOf(bsh.shared.hashSet.size()));
I guess you can use Response Assertion.
The test plan:
Create N threads
HTTP Request - POST to some URL
Verify that every request has the same string in the response with Response Assertion
When you place this assertion on the Test plan level it applies to all the threads.

JMeter: Can't copy CSV variable into another variable

I am reading a token from a .csv file into variable CSV_ACCESS_TOKEN. I have 3 request under one ThreadGroup. I want a scenario when logged in user loads a page thrice (or N time). So 1 thread is looping N time. After reading token once, I dont want to read next token in loop but want to loop through URL three (or N) time with same token.
Right now I am reading data from CSV, and using "BeanShell Sampler" inside "Once only Controller". In the sample I am using line like: vars.put("ACCESS_TOKEN",vars.get("CSV_ACCESS_TOKEN"). But that BeanShell sampler is recorded in my Summary Result. I don't want that.
I tried using "User Defined Variable" controller and try to assign the value ${__evalVar(CSV_ACCESS_TOKEN)} but it return empty value for ${ACCESS_TOKEN}. When I use ${CSV_ACCESS_TOKEN}, it shows me the values. If I use some other variable instead of CSV_ACCESS_TOKEN in UDV controller, it assigns the value from other variable and I see values for ${ACCESS_TOKEN}.
Why CSV variable is not assigning the values in regular variable.
Thanks
Vinay
If you have 3 requests, I suggest you put a Beanshell preprocessor on the first request, which copies the CSV_ACCESS_TOKEN to ACCESS_TOKEN.
Each of your samples can the use ACCESS_TOKEN, so CSV is accessed once per cycle of 3.
Each time the preprocessor run (ie before each 1st request), CSV_ACCESS_TOKEN will get updated from the dataset.
If it is the same request, which you do not wish to duplicate, you can look into use of test fragments and modules, so you can run the same sample from a variety of controllers. First from a simple controller with the preprocessor attached, and then from a loop controller to perform 2 more requests.
I think the code you have used already to manipulate the CSV values will continue to work in this scenario.

Resources