How to use array from response1 in request2 in jmeter? - 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

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: Extract Multiple values from JSON responses and store it in variable(comma seperated)

Can you please let me know efficient way to extract all ItemID from below Json response and store extracted values in a variable with coma separated.
Example: JsonResponse of a request.
[
{
"ItemID": "ITM40400002",
"deliveryId": "1",
},
{
"ItemID": "ITM40400003",
"deliveryId": "2",
},
{
"ItemID": "ITM40400002",
"deliveryId": "3",
}
]
Extracted Variable
Items = ITM40400002,ITM40400003,ITM40400002
Add JSON Extractor as a child of the request which returns the above JSON
Configure it as follows:
Names of created variables: anything meaningful, i.e. foo
JSON Path Expressions: $..ItemID
Match No: -1
Tick Compute concatenation var
That's it, the JSON Extractor will extract all the ItemID attributes values and store them into foo_ALL JMeter Variable
Demo:
More information: API Testing With JMeter and the JSON Extractor

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 iterate through the contents of a Json object

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

JMeter Modify the GET response to use in PUT

I have two requests, the first one is GET, second is PUT. I should receive the response data from GET request, modify it a little bit and send with PUT request. So far I managed to do all, except modifying the response data.
For GET request I use Regular Expression Extractor as Preprocessor:
And currently I send the PUT request without modifying the data:
JSON structure:
{
"property1" : 1,
"property2" : "2",
"innerPropery" : {
"innerProperty1" : "value1",
"innerProperty2" : "value2",
"innerProperty3" : "value3"
}
}
I should change the innerProperty2.
Thanks!
You can do it without Regular Expression Extractor interim step.
Add JSR223 PostProcessor as a child of the getForm request
Choose groovy in the "Language" drop-down
Put the following code into "Script" area:
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
def response = prev.getResponseDataAsString()
def json = new JsonSlurper().parseText(response)
def builder = new JsonBuilder(json)
builder.content.property2 = '2.1'
vars.put("response", builder.toPrettyString())
In saveForm request use ${response} as the request body
References:
Parsing and Producing JSON
Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For!
I have managed to do this via BeanShell PostProcessor. First I have added a new BeanShell PostProcessor: click right button on getFrom, Add -> Post Processors -> BeanShell PostProcessor. After that I opened the reated BeanSChell and have written the following code in Script field:
responseString = vars.get("response");
log.info("Received response: " + responseString);
responseString = responseString.replace("\"prop1\" : \"value2\"", "\"prop1\" : \"value2.1\"");
log.info("Response to send: " + responseString);
vars.put("modifiedResponse", responseString);
In Parameters field I have written:
response
Finally, I changed for PUT request the body from
${response}
to
${modifiedResponse}

Resources