How to manipulate json data in Jmeter - json

In a Jmeter Script, I need to process a http response e manipulate a json for send in next request, because actually this manipulation occurs in a Angular client.
My Http reponse:
[
{
"function":"nameA",
"rast":"F1",
"tag":"EE",
"probs":"0,987"
},
{
"function":"nameB",
"rast":"F2",
"tag":"SE",
"probs":"0,852"
},
{
"function":"nameC",
"rast":"F3",
"tag":"CE",
"probs":"0,754"
}
]
I need convert the result in json bellow to post in next request:
[
{
"function":"nameA",
"rast":"F1",
"type":{
"name":"EE"
},
"id":"alpha"
},
{
"function":"nameB",
"rast":"F2",
"type":{
"name":"SE"
},
"id":"alpha"
},
{
"function":"nameC",
"rast":"F3",
"type":{
"name":"CE"
},
"id":"alpha"
}
]
I filter the response with this JSON Extractor:
[*].["function", "rast", "tag"]
But now I need to solve other problems:
Add an id attribute (same for all functions)
Add an object with the name type.
Move the tag attribute into the object called type.
Rename the tag attribute to the name.

Add JSR223 PostProcessor as a child of the request which returns the original JSON
Put the following code into "Script" area:
def json = new groovy.json.JsonSlurper().parse(prev.getResponseData()).each { entry ->
entry << [type: [name: entry.get('tag')]]
entry.remove('tag')
entry.remove('probs')
entry.put('id', 'alpha')
}
def newJson = new groovy.json.JsonBuilder(json).toPrettyString()
log.info(newJson)
That's it, you should see the generated JSON in jmeter.log file.
If you need to have it in a JMeter Variable add the next line to the end of your script:
vars.put('newJson', newJson)
and you will be able to access generated value as ${newJson} where required
More information:
Groovy: Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

Related

How to parse dynamic json reponse and get specific value and pass it as an input to next request

I get .json file as a response from an API and from that file I should parse and fins specific parameter and pass it as an input to the next request, how do I do that using Katalon.
If I say
response = JSON.parse("response.json");
it says it is unable to identify JSON as valid. Can someone help me out with the solution?
Your JSON is invalid, maybe it is a copy-paste issue.
The valid JSON should be
{
"responseStatusCode": "OK",
"data": {
"screenName": "employeeTimeslip",
"screenType": "Redirect",
"searchResultCount": 0,
"rows": [],
"tabs": [],
"searchParams": {
"employeeID": "000092926",
"timeslipNumber": "201900019701"
}
}
}
So, you were missing a "," between "OK" and "data" and two closing curly braces at the end of the file.
You can check JSON files for validity yourself using online JSON validators, for example, this one.
i found a way to read specific parameter from the json response file like below:
val scn = scenario("ClaimSubmission")
.exec(http("request_2")
.post("URL")
.headers(headers_2)
.body(RawFileBody("json file path"))
.check(jsonPath("$..timeslipnumber").find.saveAs("timeslipnumber")))
Timeslip number would be retrieved using : .check(jsonPath("$..timeslipnumber").find.saveAs("timeslipnumber")))

JSR223 Preprocessor give Bad request while creating json in Jmeter using CSV

I am trying to create a JSON using Groovy Json Builder in Jmeter.
Below is the code I created to get the desired JSON :
import groovy.json.JsonBuilder
def json = new JsonBuilder()
json {
"Rule":{
"__type":"AndroidSamsungDeviceRelocationRule",
"RuleId":0,
"Name":"Test",
"DeviceFamily":6,
"Targets":{
"Groups":[
{
"Id":"[{LogicalId="${logicalid1}"}]"
}
],
"Devices":[
]
},
"Priority":0,
"IsEnabled":true,
"StartDate":"/Date(${__time(,)})/",
"EndDate":null,
"Mappings":[
{
"RelocationTarget":{
"Id":"${logicalid2}",
"Name":"${__P(TargetGroups)}",
"Path":"\\'${__P(TargetGroups)}'\\",
"PathVisible":"\\'${__P(TargetGroups)}'\\"
},
"IPRange":[
source Double.parseDouble(vars.get("source"))
destination Double.parseDouble(vars.get("destination"))
]
}
],
"EnrollmentCertificateId":null,
"EnrollmentCertificateName":""
}
}
sampler.addNonEncodedArgument("",json.toPrettyString(),"")
sampler.setPostBodyRaw(true)
CSV data is as follows:
0.0.0.0,255.255.255.255
10.0.0.1,255.0.0.0
The above CSV can have multiple values from 1 to 100 IPs separated by ',' .
The code also needs to be modified as per the number of IPs rows.
The ABove CSV data needs to be there under IPRange tag and Result Should be like:
"Rule":{
"__type":"AndroidSamsungDeviceRelocationRule",
"RuleId":0,
"Name":"Test",
"DeviceFamily":6,
"Targets":{
"Groups":[
{
"Id":"[{LogicalId="${logicalid1}"}]"
}
],
"Devices":[
]
},
"Priority":0,
"IsEnabled":true,
"StartDate":"/Date(${__time(,)})/",
"EndDate":null,
"Mappings":[
{
"RelocationTarget":{
"Id":"${logicalid2}",
"Name":"${__P(TargetGroups)}",
"Path":"\\'${__P(TargetGroups)}'\\",
"PathVisible":"\\'${__P(TargetGroups)}'\\"
},
"IPRange":[
{"From":"0.0.0.0","To":"255.255.255.255"},
{"From":"10.0.0.1","To":"255.0.0.1"},
......
.....
]
}
],
"EnrollmentCertificateId":null,
"EnrollmentCertificateName":""
}
But the issue I am getting is "Bad Request" in jmeter.
I fail to see why do you need to build your request body in Groovy, it can be done purely in HTTP Request "Body Data" tab like:
Check out JMeter Parameterization - The Complete Guide for examples on using external data sources for creating data-driven JMeter tests
If you want us to help you with the setup it would be good to see the desired outcome, i.e. JSON payload you would like to generate and the code you've tried as above samples don't make any sense. Get used to check jmeter.log file - normally it contains enough information to get to the bottom of the JMeter test issue. Also I suggest reading Parsing and producing JSON article and JsonBuilder class documentation.

How to store entire response and update it for next rest call using Jmeter

Question: How to extract entire restAPI response and modify it with some values and use the updated response for sub-sequent rest call. I am using Jmeter
Question Scenario:
I have one POST call ex: "/check1/id1/post"
POST body :
{
"test":"rest",
"check" :{
"id":1,
"name": "xyz"
}
}
POST call RESPONSE :
{
"test":"rest",
"check" :{
"id":1,
"name": "xyz"
"status":"updated"
}
}
=====================================================================
QUESTION: Now, I have to use entire above RESPONSE in next POST Call body as below, BUT, I wanted to update "id" value as 2 and then need to POST rest call.
REST CALL: ------ > "/check1/id2/post"
POST BODY as below : ------->
{
"test":"rest",
"check" :{
"id":2,
"name": "xyz"
"status":"updated"
}
}
=============================================================
Can anyone please guide on this? , I am clueless about how to solve this issue?, I need to solve this using Jmeter.
To store entire response:
add Regular Expression Extractor as a child of the request which response you want to capture
configure it as follows:
Reference name: anything meaningful, i.e. response
Regular Expression: (?s)(^.*)
Template: $1$
To replace 1 with 2 you can go for __strReplace() function like ${__strReplace(${response},1,2,)}. Note that you need to install Custom JMeter Functions bundle using JMeter Plugins Manager in order get it.
You can do this using beanshell or JSR223 PreProcessor
Assuming a valid JSON
{
"test":"rest",
"check" :{
"id":1,
"name": "xyz",
"status":"updated"
}
}
Here are the steps
Add a JSR223 preprocessor to the 2nd post request.
Add the following code to the preprocessor
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
def slurped = new JsonSlurper().parse(prev.getResponseData())
def builder = new JsonBuilder(slurped)
builder.content.check.id = '2'
vars.put("POSTDATA",builder.toPrettyString())
Above code will update ID value with 2 and stores the JSON in POSTDATA , you can use ${POSTDATA} to post the JSON FILE
In my pre processor i'm saving the response using prev.getResponseData() , that means this pre processor must included with the sampler right next to the first sampler.
For more information on beanshell Please follow this link

Jmeter - How to validate portions of response json

I have the following json:
{
"content":
[
{
"id":1,
"userId":2,
"storeId":8,
"userFirstName":"Max",
"userLastName":"Mustermann",
"city":"Berlin",
"spendQuantity":100,
"paymentStatus":"UNPAID",
"userBalanceStatus":null,
"rateObject":
{
"identifier":23,
"id":"432",
"rate":"1.9345345",
"symbol":"USD",
"rank":2,
}
},
{
"id":2,
"userId":2,
"storeId":3,
"userFirstName":"Newman",
"userLastName":"Mustermann",
"city":"Berlin",
"spendQuantity":1000,
"paymentStatus":"UNPAID",
"userBalanceStatus":null,
"rateObject":
{
"identifier":3,
"id":"234",
"rate":"1.922222245345",
"symbol":"USD",
"rank":2,
}
},
{
"id":3,
"userId":2,
"storeId":3,
"userFirstName":"Newman",
"userLastName":"Mustermann",
"city":"Munich",
"spendQuantity":3000,
"paymentStatus":"UNPAID",
"userBalanceStatus":null,
"rateObject":
{
"identifier":2332,
"id":"234",
"rate":"3.234234",
"symbol":"USD",
"rank":2,
}
},
{
"id":4,
"userId":2,
"storeId":3,
"userFirstName":"Newman",
"userLastName":"Mustermann",
"city":"Essen",
"spendQuantity":4000,
"paymentStatus":"UNPAID",
"userBalanceStatus":null,
"rateObject":
{
"identifier":234,
"id":"234",
"rate":"333.234234",
"symbol":"USD",
"rank":2,
}
}
}
But I need to verify it partially - Only the fields in the nested jsons where city is Berlin or Essen, but without the rateObject (I don't need to verify this part). With other words I need to verify nested jsons with ids- 1,2,4 - all fields, without the information in rateObject.
Partial Answer and Suggestion:
We can apply the filter condition in the JSON Query to fetch the matched details.
For Example: To get the id of the mentioned city,
JSON Query:
$.content[?(#.city=="Berlin" || #.city=="Essen")].id
Output:
[
1,
2,
4
]
Similarly, you can assert all the required fields using the filter JSON Query.
JMeter JSON Extractor will provide only one value at a time.So, you can either add some logic to verify all the occurrences or multiple verification can be added by specifying the id index ( $.content[?(#.city=="Berlin" || #.city=="Essen")].id[0] --> It gives the first occurrence Id )
If you want to validate multiple fields,then you can write the customized script in Bean Shell Post Processor.(Refer the below link and you will get some idea)
Extracting JSON Response using Bean Shell Postprocessor
If you are using the Bean Shell Post Processor, then required java jar files should be placed in JMeter ClassPath( Folder: apache-jmeter-4.0\lib\ext)

Jmeter Dynamic Json Array Generation from CSV file

I have a following Json data to post.
{
"id": 1,
"name": "Zypher",
"price": 12.50,
"tags": [{
"tag": 1,
"tagName": "X"
},
{
"tag": 2,
"tagName": "Y"
},
{
"tag": 2,
"tagName": "Z"
}]
}
My Jmeter Test Plan is as following,
- Test Plan
- Thread Group
- Http Request Defaults
- Http Cookie Manager
- Simple Controller
- CSV Data Set Config (Sheet_1)
- Http Header Manager
- Http Request (The hard coded json was provided here as body data)
Every thing works fine. Now I want to use csv to parametrised my Json.
Sheet_1:
id,name,price
1,Zypher,12.50
I modified json with these 3 parameters and its works for me. Now I want to parametrise detail portion. I have no idea how to do this.
All I want to keep my json like this,
{
"id": ${id},
"name": ${name},
"price": ${price},
"tags": [
{
"tag": ${tag},
"tagName": ${tagName}
}]
}
How could I dynamically make json array tags for details portion from csv data? I want it to be looped as row provided in csv file.
Updated csv
id,name,price,tag,tagname
1,Zypher,12.50,7|9|11,X|Y|Z
It would be great in this format
id,name,price,tag
1,Zypher,12.50,7:X|9:Y|11:Z
tag has two properties dividing by :
You can do it using JSR223 PreProcessor and Groovy language, something like:
Given you have the following CSV file structure:
id,name,price,tag
1,Zypher,12.50,X|Y|Z
And the following CSV Data Set Config settings:
Add JSR223 PreProcessor as a child of the HTTP Request sampler and put the following code into "Script" area:
import groovy.json.JsonBuilder
def json = new JsonBuilder()
def tagsValues = vars.get("tags").split("\\|")
class Tag {int tag; String tagName }
List<Tag> tagsList = new ArrayList<>()
def counter = 1
tagsValues.each {
tagsList.add(new Tag(tag: counter, tagName: it))
counter++
}
json {
id Integer.parseInt(vars.get("id"))
name vars.get("name")
price Double.parseDouble(vars.get("price"))
tags tagsList.collect { tag ->
["tag" : tag.tag,
"tagName": tag.tagName]
}
}
sampler.addNonEncodedArgument("",json.toPrettyString(),"")
sampler.setPostBodyRaw(true)
Remove any hard-coded data from the HTTP Request sampler "Body Data" tab (it should be absolutely blank)
Run your request - JSON payload should be populated dynamically by the Groovy code:
References:
Parsing and producing JSON - Groovy
Groovy Is the New Black
Update:
for CSV format
id,name,price,tag
1,Zypher,12.50,7:X|9:Y|11:Z
Replace the below Groovy code:
List<Tag> tagsList = new ArrayList<>()
def counter = 1
tagsValues.each {
tagsList.add(new Tag(tag: counter, tagName: it))
counter++
}
with
List<Tag> tagsList = new ArrayList<>();
tagsValues.each {
String[] tag = it.split("\\:")
tagsList.add(new Tag(tag: Integer.parseInt(tag[0]), tagName: tag[1]))
}