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
Related
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?
I am using jmeter for performance testing & stuck at a point. I have to process a request with multiple users & before I process the request to an API endpoint, I have to iterate on all users & need to update the "ConsentDate" to system.DateTime. So please help me with a solution, i am a beginner to the jmeter framework.
I am trying to take help of JSR223 PreProcessor .
Please find the screen shot.
Jmeter
I am reading the json from a CSV file & My request structure looks like below,
{
"Company": {
"User": {
"u1": {
"id": "1001",
"consent": "Yes",
"consentDate": "2020-03-14T17:44:56.224Z"
},
"u2": {
"id": "1002",
"consent": "No",
"consentDate": "2020-03-14T17:44:56.224Z"
}
}
}
}
Oh, that's very easy, please find the screen shot
More information:
Apache Groovy - Parsing and producing JSON
Apache Groovy - Why and How You Should Use It
Text version of the code just in case, going forward please post code as text, not as image:
def data = new org.apache.jmeter.config.Arguments()
def request = new groovy.json.JsonSlurper().parseText(sampler.getArguments().getArgument(0).getValue())
def now = new Date().format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
request.Company.User.each { user ->
user.getValue().consentDate = now
}
def body = new org.apache.jmeter.protocol.http.util.HTTPArgument('', new groovy.json.JsonBuilder(request).toPrettyString(), '', false)
body.setAlwaysEncoded(false)
data.addArgument(body)
sampler.setArguments(data)
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
I have the below json
{
"swagger": "2.0",
"info": {
"version": "v2",
"title": "Portfolio"
},
"host": "portfolio.com",
"schemes": [
"https"
],
"paths": {
"/v2/clients/{clientId}/assets": {
"get": {
"tags": [
"assets"
There are multiple paths I want to extract but they all start /v2/clients so what Im looking for is everything that starts with /v2/clients but none of the sub-data that sits the below, just the full paths between the ""
I am using jmeter JSON extractor and if I use $.paths it starts at this point but brings through all the mass amount of sub-data. I've tried looking around stackoverflow but can't find exactly what I am looking for. Any help appreciated
I believe the easiest would be going for JSR223 PostProcessor and Groovy language
Add JSR223 PostProcessor as a child of the request which returns above JSON
Put the following code into "Script" area:
def index = 1
new groovy.json.JsonSlurper().parse(prev.getResponseData()).paths.each { path ->
if (path.getKey().startsWith('/v2')) {
vars.put('path_' + index, path.getKey())
index++
}
}
That's it, you will have JMeter Variables like:
path_1=/v2/clients/{clientId}/assets
path_2=/v2/foo/bar
path_3=/v2/baz/qux
etc.
More information:
JsonSlurper
Apache Groovy: Parsing and producing JSON
Apache Groovy - Why and How You Should Use It
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