How to update Json file before sending as a request in Jmeter - jmeter

In my Project, API Contract is changing frequently (every two sprints). From me it is very hard to update the payload in each 'http request' of project test cases.
I am looking for a solution to maintain a separate json file with the request. Update the request json file based on the test cases using Jmeter and send to server.
Do we have any solution for this?
Or please suggest if we have any other approach to handle this case.
sample JSON: original JSON has more than 600 lines.
{
abc:"abc",
xys:"xyz",
"abcd":[{
abc:"abc",
xys:"xyz",
abc:"abc",
xys:"xyz"
PQR:[{
abc:"abc",
xys:"xyz",
abc:"abc",
xys:"xyz",
}]}]
}

I can think of only one option:
Add JSR223 PreProcessor, it will be executed before the request
JSON file can be read using JsonSlurper
At this stage you can amend it according to your needs using Groovy language
Once you done you can construct the JSON back using JsonBuilder and write the generated new JSON back to the file
More information: Apache Groovy - Parsing and producing JSON

Related

Is it possible to parameterize Post requests payload and then encode it to base64 in Jmeter

The background is that I want to make a REST to Google pub/sub. Where the data need to follow this format:
Link to documentation of Pub/Sub format
My current solution is that I uses an BeanShell PreProcessor script to encode the payload to base64 before I send the request to the endpoint. This solution works, but I would like to
parameterize the data in the payload, instead of having the whole payload inserted as test data in the csv-file.
BeanShell PreProcessor used to encode the message before it is being sent:
import org.apache.jmeter.protocol.http.util.Base64Encoder;
String csv_payload = vars.get("csv_payload");
String csv_payload_encoded = Base64Encoder.encode(csv_payload);
vars.put("csv_payload_encoded", csv_payload_encoded);
Payload populated from the csv-file in Post request:
{
"messages": [
{
"data":"${csv_payload_encoded}",
}
]
}
Example of payload data stored in the csv-file that is sent in the request:
{"identId":"123456","requestId":null,"payload":{"header":{"requestid":1,"timeStamp":1617873956,"version":"0.0.0.1","eventId":0001,"creatorId":0,"messageTTL":34560},"body":{"checkid":001,"checkData":{"diagnosticsData":{"troubleSource":0,"data":"[2020-01-01 16:00:53.707961][[lat[0]][long[0]][alt[0]][canbetrust[0]][mars[0]]][signal[5]][TEM2 wake up]"}}}}}
Example of the encoded payload that the request sends to google pub/sub:
{
"messages": [
{
"data":"eyJpZGVudElkIjoiMTIzNDU2IiwicmVxdWVzdElkIjpudWxsLCJwYXlsb2FkIjp7ImhlYWRlciI6eyJyZXF1ZXN0aWQiOjEsInRpbWVTdGFtcCI6MTYxNzg3Mzk1NiwidmVyc2lvbiI6IjAuMC4wLjEiLCJldmVudElkIjowMDAxLCJjcmVhdG9ySWQiOjAsIm1lc3NhZ2VUVEwiOjM0NTYwfSwiYm9keSI6eyJjaGVja2lkIjowMDEsImNoZWNrRGF0YSI6eyJkaWFnbm9zdGljc0RhdGEiOnsidHJvdWJsZVNvdXJjZSI6MCwiZGF0YSI6IlsyMDIwLTAxLTAxIDE2OjAwOjUzLjcwNzk2MV1bW2xhdFswXV1bbG9uZ1swXV1bYWx0WzBdXVtjYW5iZXRydXN0WzBdXVttYXJzWzBdXV1bc2lnbmFsWzVdXVtURU0yIHdha2UgdXBdIn19fX19",
}
]
}
If there are any feedback I would appreciate it or any other improvements suggestion
for how I would be able to proceed in order to parameterize and encode the payload to base64 eg:
Example of
Don't use Beanshell, since JMeter 3.1 you're supposed to be using JSR223 Test Elements and Groovy language for scripting
There is __base64Encode() function available via Custom JMeter Functions plugin bundle installable using JMeter Plugins Manager
If you CSV file has references to other JMeter Functions or Variables you can resolve them by wrapping into __eval() function like:
to read the file:
${__FileToString(somefile.csv,,)}
to read the file and resolve any functions or variables in it:
${__eval( ${__FileToString(somefile.csv,,)})
to read the file, resolve any functions or variables and Base64-encode the result:
${__base64Encode(${__eval( ${__FileToString(somefile.csv,,)})},)}
Demo:

JMETER: Need to send all entries in a CSV file to HTTP request body in 'one' request

I'm trying to solve a test data issue in Jmeter. Can anyone of you have a look at below problem statement and advise here please ?
Requirement: Need to send all entries in a CSV file to HTTP request body in 'one' request to the end point.
Example CSV File:
"adsfas123wsf00000wqefqwe52145t10000",
"fdfrgvergq120947r0000dwsfqwaef237sadf",
"wfrqwef7865034r78tkahsefjh6985r7asfdaf",
"qefqwe52145t10000adsfas123wsf00000w",
"wsfqwaef237sadffdfrgvergq120947r0000d"
HTTP Request Body:
["${data}"}]
When the data is substituted, I should be able to get below output.
[
"adsfas123wsf00000wqefqwe52145t10000",
"fdfrgvergq120947r0000dwsfqwaef237sadf",
"wfrqwef7865034r78tkahsefjh6985r7asfdaf",
"qefqwe52145t10000adsfas123wsf00000w",
"wsfqwaef237sadffdfrgvergq120947r0000d"
]
Problem Statement: When I use CSV data set config. file, I'm unable to concatenate all entries into one single request body. My understanding is, CSV data set config. the file is not the right option here.
Did some search in StackOverflow and followed a method to achieve above using JSR223 PreProcessor' and the link is, How to send multiple json body using jmeter?.
Followed the above link and tried added below custom code provided.
def builder = new StringBuilder()
new File('/path/to/plans.csv').readLines().each { line ->
builder.append(new File(line).text).append(System.getProperty('line.separator'))
}
sampler.getArguments().removeAllArguments()
sampler.addNonEncodedArgument('', builder.toString(), '')
sampler.setPostBodyRaw(true)
Upon running, I get below error message,
Caused by: java.io.FileNotFoundException,
"adsfas123wsf00000wqefqwe52145t10000",
"fdfrgvergq120947r0000dwsfqwaef237sadf",
"wfrqwef7865034r78tkahsefjh6985r7asfdaf",
"qefqwe52145t10000adsfas123wsf00000w",
"wsfqwaef237sadffdfrgvergq120947r0000d" (The filename, directory name, or volume label syntax is incorrect)
If the file is not found, then how come the entries are read and displayed in the log viewer?
Also, how do I link the output of custom code to the request body? Or is it taken care of by the custom code itself?
You have an error in your code, change this line:
builder.append(new File(line).text).append(System.getProperty('line.separator'))
to this one:
builder.append(line).append(System.getProperty('line.separator'))
If you want to send the full contents of the file you don't even need to go for scripting, you can use __FileToString() function right in the "Body data" tab of the HTTP Request sampler:
${__FileToString(/path/to/plans.csv,,)}
And last but not the least if you need to generate JSON from the plain text it might be a better idea to go for JsonBuilder class, see Apache Groovy - Why and How You Should Use It and Apache Groovy - Parsing and producing JSON
Two steps:
Add a User Parameter Pre-processor before the HTTP request:
Name: DATA
User_1: ${__FileToString(/path/to/plans.csv,,)}
Add the following to request body:
${DATA}

How can I dynamically post Request body (xml) and validate the response (xml)?

Is there a way to send the XML request dynamically and validate the XML response?
My scenario is:
I will have a CSV dataset config and inside the csv file I will have two column, the first one is for the inputXMLFilePath and the second column is the expectedXMLResposneFilePath.
So I need to have a JSR233 PreProcessor under HTTP request sampler, read the input file path convert it to the post body, and also has another JSR233 sampler for load the expected response from the expectedXMLResponseFilePath and compare it with the previous XML response. I have a snippet for JSON which is working fine. but for XML how can I do it?
You can use __FileToString() function for both use cases:
To send the XML request body, like ${__FileToString(${inputXMLFilePath},,)} (where ${inputXMLFilePath} is the variable from the CSV Data Set Config)
To validate the response using Response Assertion configured like:
Field to Test: Text Response
Pattern Matching Rules: Equals
Patterns to test: ${__FileToString(${expectedXMLResponseFilePath},,)}
You can use JMeter Functions literally at the any place of your Test Plan so their flexibility is higher than for other test elements. Also JMeter Functions are being compiled into native Java code therefore their execution speed will be higher and footprint will be less comparing to Groovy scripting.
Check out Apache JMeter Functions - An Introduction article to learn more about JMeter Functions concept.

how to format JSON response in Jmeter?

How can I format json response in jmeter?
I don't want to tell which part of json answer
should be showed. I want to see my response not as
very long one line but as many lines formatted with new lines and
tabs/spaces.
I saw:
http://eclipsesource.com/blogs/2014/06/12/parsing-json-responses-with-jmeter/
Jmeter extracting fields/parsing JSON response
Thanks in advance!
I believe JSON Formatter PostProcessor is what you're looking for
If it is not suitable for you - take a look at JSR223 PostProcessor, it provides prev pre-defined variable (basically SampleResult instance) which gives read/write access to the parent sampler(s) response data so you will be able to do anything you want with the response using Groovy language

Anyway to auto set jmeter assertions to initial responses?

I am building out a test suite in jmeter and want to set the assertions to the initial responses that I get from the api calls. Is there any way to do this besides copy pasta?
For clarity each individual call has its own assertion, which for the moment is the response it is receiving.
I want the assertions to be populated by the responses.
If I understood currectly - you are coming up with some JMeter-Baseline script - you also assume that the response you get now is correct - that is what you expect to get it in future as well , so you want to put the response data in the assertion.
If yes, JMeter will not remember the initial responses. So you need to create your script accordingly.
You can have a beanshell postprocessor to write the the responsedata in a CSV file. Later you modify the script to look for the assertion string from CSV file to compare. This is the statement to get the Response Data.
prev.getResponseDataAsString()
As per How to Use JMeter Assertions in 3 Easy Steps guide, JMeter Assertions have their scope.
If you put an assertion at the same level as all requests it'll apply to all of them. See image below for explanation:
I would use a CSV file with the URL and the assertion string you want to match.

Resources