How to iterate through the contents of a Json object - jmeter

On the JSR223 assertion in Jmeter, I need to validate only the inner part of the JSON returned.
I followed this thread to get an idea on the validation.
​How can I write JSON schema validation for JMeter run in TeamCity
Basically my Jmeter sampler returns the json as follows. On my schema, the validation should be for items, service and requestId. No validation should be performed for "payload".
{
"payload": [
{
"items": [
{
"code": "487482378",
"description": "Alpha Co",
"valid": true
},
{
"code": "92901128365",
"description": "Beta Co",
"valid": true
}
],
"service": "entities",
"requestId": "d190219"
}
]
}
This is my current code in the js223 sampler:
var schemaPath = '/path/entities-schema.json'
var rawSchema = new org.json.JSONObject(new org.json.JSONTokener(org.apache.commons.io.FileUtils.readFileToString(new java.io.File(schemaPath), 'UTF-8')))
var schema = org.everit.json.schema.loader.SchemaLoader.load(rawSchema)
schema.validate(new org.json.JSONObject(prev.getResponseDataAsString()))

You can remove the "unwanted" part of the response using JSR223 PostProcessor like:
def before = prev.getResponseDataAsString()
log.info('Before: ' + before)
def response = new groovy.json.JsonSlurper().parseText(before)
def after = new groovy.json.JsonBuilder(response.payload.items).toPrettyString()
log.info('After: ' + after)
prev.setResponseData(after, 'UTF-8')
Once done you can use your JSON Schema validation approach against the new content without elements you don't need.
References:
Groovy: Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

Related

JMeter - How to add data to request body in every loop?

I'm working with an API that returns response in the following format:
"products": [
{
"name": "ABC"
"id": "ABCDEFG"
"Status":Open
}
{
"name": "XYZ"
"id": "LMNOPQ"
"Status":Open
} ]
The number of products varies and so does the number of IDs generated. I need to extract all id values which I'm doing using a JSON extractor and setting the match number to -1.
I need to pass these ID values in this request:
"products": [
{
"id": "id1"
}
{
"id": "id2"
} ]
If there are 5 IDs then the request needs to contain 5 id values.
I've tried using loops but I can't figure out how to add a { "id": } to the request body on every iteration of the loop. Is there any way to simulate this?
Instead of using JSON Extractor you could do everything with JSR223 PostProcessor and extract the IDs and build the next request body in one shot.
Example code:
def ids = new groovy.json.JsonSlurper().parse(prev.getResponseData()).products.collect { product -> product.id }
def payload = [:]
def products = []
ids.each { id ->
products.add([id: id])
}
payload.put('products', products)
vars.put('payload', new groovy.json.JsonBuilder(payload).toPrettyString())
You will be able to refer generated value as ${payload} where required.
More information:
Apache Groovy: Parsing and producing JSON
Apache Groovy: What Is Groovy Used For?

Jmeter - How to get nested object in json with multiple object

I have this json:
{
"deviceId": "deviceCustom",
"moduleId": "custom",
"properties": {
"desired": {
"settings": {
"ef78c18c-2291-4d15-ae87-d89abb9b1fef": {
"name": "elements",
"version": "1.0.0",
"category": "A1"
},
"f4b04c94-4643-4b13-b10c-9a00fbf4ea27": {
"name": "tags",
"version": "2.0.0",
"category": "B1"
}
}
}
}
}
and I would like to get separately all the objects under "settings". E.g:
settings_1="f4b04c94-4643-4b13-b10c-9a00fbf4ea27":{"name":"tags","version":"2.0.0","category":"B1"}
settings_2="ef78c18c-2291-4d15-ae87-d89abb9b1fef":{"name":"elements","version":"1.0.0","category":"A1"}
settings_matchNr=2
In Jmeter I've configured a JSON Extractor with this JSON Path expression: $.properties.desired.settings but I got this result:
settings_1={"f4b04c94-4643-4b13-b10c-9a00fbf4ea27":{"name":"tags","version":"2.0.0","category":"B1"},"ef78c18c-2291-4d15-ae87-d89abb9b1fef":{"name":"elements","version":"1.0.0","category":"A1"}}
settings_matchNr=1
I've also tried to use JSR223 Post Processor with Slurper but no valid result.
Could you help me on that?
Thanks in advance.
Add JSR223 PostProcessor as a child of the request which returns the above JSON
Put the following code into "Script" area:
new groovy.json.JsonSlurper().parse(prev.getResponseData()).properties.desired.settings.entrySet().eachWithIndex { entry, index ->
def setting = [:]
setting.put(entry.getKey(), entry.getValue())
vars.put('setting_' + (index + 1), new groovy.json.JsonBuilder(setting).toPrettyString())
}
That's it, you will be able to refer the extracted JSON Objects as ${setting_1} and ${setting_2}
More information:
Apache Groovy - Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

How to use array from response1 in request2 in jmeter?

I am trying to extract a jsonArray from response of request1 and use it in request2. I am using JSONextractor the steps in this question but I am getting the array as different variables instead of 1 jsonArray.
My JsonExtractor:
Output of debug sampler:
Request:
{
"items": [
{
"id": "asd"
},
{
"id": "def"
},
{
"id": "hij"
}]
}
I don't know what I'm doing wrong that is extracting values in different variables instead of 1 jsonArray.
You can generate a JSON request body from the JMeter Variables which are coming from the JSON Extractor using JSR223 PreProcessor
Add JSR223 PreProcessor as a child of the request which you want to parameterize
Put the following code into "Script" area:
def payload = [:]
def items = []
1.upto(vars.get('userIds_matchNr') as int, { index ->
items.add([id: vars.get('userIds_' + index)])
})
payload.put('items', items)
vars.put('payload', new groovy.json.JsonBuilder(payload).toPrettyString())
You should be able to put the ${payload} JMeter Variable reference into the request "Body Data" tab
Demo:
More information:
Apache Groovy - Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

How do i remove empty parameter using beanshell preprocessor in jmeter

I am trying to read a csv file that contains more that 500+ rows and each row will serve as request to API. Now my problem is that some of the parameters have empty string and i would like to set up a condition in case if parameter returns empty string then remove that parameter from request body upfront before hitting the API
Below is my json
{
"body": {
"Id1": "${Id1}",
"addressId": "${addressId}",
"languageCode": "${languageCode}",
"tempId": "${tempId}"
}
Now after reading csv i get following values in my request body
{
"body": {
"Id1": "1",
"addressId": "1233",
"languageCode": "E",
"tempId": ""
}
As you can see tempId has empty string. Now using bean-shell preprocessor i am trying to remove this but no luck
Object requestBody = sampler.getArguments().getArgument(0).getValue();
if (requestBody.get("tempId").equals("")){
sampler.getArguments.removeArgument("tempId");
}
when i look into result tree i don't see tempId being deleted from the request. I would appreciate any help
Avoid using Beanshell for deprecation and bad performance.
Use groovy instead with this code:
import org.apache.jmeter.config.Arguments;
def request = new groovy.json.JsonSlurper().parseText(sampler.getArguments().getArgument(0).getValue())
def newRequest = evaluate(request.inspect())
request.body.each { entry ->
if (entry.getValue().equals('')) {
newRequest.body.remove(entry.getKey())
}
}
def arguments = new Arguments();
sampler.setArguments(arguments);
sampler.addNonEncodedArgument('', new groovy.json.JsonBuilder(newRequest), '')
sampler.setPostBodyRaw(true)
See:
JsonSlurper
JsonBuilder
If you're looking to learn jmeter correctly, this book will help you.
Replace in body "tempId": "${tempId}" with ${tempIdEval} and calculate value in JSR223 script
String tempIdEval = vars.get("tempId");
vars.put("tempIdEval", (port == null ? "" : "\"tempId\": \"" + tempIdEval + "\""));
Migration to JSR223 PreProcessor+Groovy is highly recommended for performance, support of new Java features and limited maintenance of the BeanShell library.
Since you are using beanshell preprocessor, we can use like
if (vars.get("tempId")!="")
vars.put("variablename","not null");
else
vars.put("variablename","is null");
and use the "variablename" instead. You can manipulate the string as well as below.
if (${tempId}=="")
{ vars.put("json","
{
"body": {
"Id1": "${Id1}",
"addressId": "${addressId}",
"languageCode": "${languageCode}""
}
}
else
{ vars.put("json","
{
"body": {
"Id1": "${Id1}",
"addressId": "${addressId}",
"languageCode": "${languageCode}",
"tempId": "${tempId}"
}
}
Be aware that since JMeter 3.1 it's recommended to use JSR223 Test Elements and Groovy language
The relevant Groovy code for JSR223 PreProcessor which removes JSON attributes with empty values would be something like:
def request = new groovy.json.JsonSlurper().parseText(sampler.getArguments().getArgument(0).getValue())
def newRequest = evaluate(request.inspect())
request.body.each { entry ->
if (entry.getValue().equals('')) {
newRequest.body.remove(entry.getKey())
}
}
sampler.getArguments().removeAllArguments()
sampler.addNonEncodedArgument('', new groovy.json.JsonBuilder(newRequest).toPrettyString(), '')
sampler.setPostBodyRaw(true)
More information:
Groovy: Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

How to remove array present in Json in jmeter

I have a json and I have to remove whole filter block from that ,How can i remove that?I tried below in JSR223PostProcessor but it is not working
var response = prev.getResponseDataAsString();
var responseWithoutIds = response.replaceAll("\"filter\"[ ]*:[^,}\\]]*[,]?", "");
{
"templateId": "1e5eef7d-9581-40a1-98ed-774dcf68ce11",
"ownerId": "241e992f-a1c7-430a-be9f-347337643697",
"orgId": "4c41a6d7-dfbf-485b-84b6-3a3991546d9c",
"createdDate": "2018-12-24T10:51:57.336Z",
"shareWithOrg": false,
"templateName": "custom template",
"templateDesc": null,
"system": false,
"optionIds": [
"9c9b93c9-4ada-4489-9129-604cf1fa35be",
"65285021-9c2c-4787-b810-390c50f48f9f",
"222c832d-8db6-4ca1-88ef-150b6a388d87",
"be22ba29-144b-4971-99de-0d4258220558",
"b7ab883b-fe51-4e02-bdb1-0d7321d30ac3",
"510660fa-d255-45e2-b6b8-c1c09c9009d6",
"51f78f08-b655-4a82-b0c5-61365881fb0a",
"ac1d4b39-f41c-4b69-bdc4-b76fd1d2b9af",
"2de3591e-c9eb-48bd-a9bf-acfcee695ac8",
"c9e2a1f1-f786-4e9a-9d11-525a5aa01345",
"441a0627-9983-4edc-95ce-a5b8e79f7f1d",
"087a1ac8-e7c1-4cee-ae31-4f0aaccba8c9",
"dba760fb-9e97-4dcb-b1ab-4a2795e59ee6",
"53bc5244-b33e-4732-8bf0-cd051e017089",
"2bf04285-fe19-4534-8467-44c08661da60",
"020eb946-6ba0-4519-b6f9-23ffafd949d0",
"ced89c82-5ba1-4fe6-bc83-5bddff820c85",
"18ea7006-2e29-4a3f-a28f-59a1323a4bd0",
"c7efa0d1-094c-4626-90aa-80e1343bbdef",
"6504605f-3a41-4406-9f0e-150365c8ee35",
"3c28c622-83b1-4b46-ac16-3c5cbff80999",
"6a227b18-519f-49c4-8c59-7fe0eaf73fea",
"f9127d4e-c27e-48fa-8286-42a045d8fc40",
"bb695a06-50fe-4419-924f-7fee96530b63",
"731393bc-92e0-4ddb-8113-a7b3942527c5",
"a355ee2d-c654-4406-9027-8e801cb1a4a9"
],
"optionGroupIds": [
"09f1302b-6ad0-486b-8f8c-e65ae14f5831",
"2041206d-cc87-4173-912c-fee52cefcf2b",
"6fc154fb-8313-488c-a2cb-e1a5b88b3028",
"cc0767f2-3e7f-42f1-b9c7-9f76991a6fcf",
"4cd75ade-db20-43fe-8b15-7effa961b4b5",
"6af8ddba-8a7c-4ff7-8043-6358b6e6a31b"
],
"filter": [
{
"optionId": "222c832d-8db6-4ca1-88ef-150b6a388d87",
"selectedValues": [
"all"
],
"selectedComplexValues": null,
"contextualFilterId": null,
"operator": "pastDays",
"filterType": "date"
}
],
"sortDirection": "desc",
"sortedOptionId": "222c832d-8db6-4ca1-88ef-150b6a388d87",
"templateCategory": "patients"
}
Using regular expressions is not the best way to proceed. Also consider switching to Groovy language, it provides JsonSlurper and JsonBuilder classes which way more reliable.
Example code:
def response = new groovy.json.JsonSlurper().parse(prev.getResponseData())
response.remove('filter')
def responseWithoutIds = new groovy.json.JsonBuilder(response).toPrettyString()
log.info(responseWithoutIds)
References:
Groovy: Parsing and producing JSON
Apache Groovy - Why and How You Should Use It
Use below code in JSR223PostProcessor :
var body = prev.getResponseDataAsString();
var parsed = JSON.parse(body);
delete parsed.filter[0];
delete parsed.filter;
vars.put('value', JSON.stringify(parsed));

Resources