Saving matched values in JMeter postprocessors - jmeter

In just starting to use JMeter I am trying to set variables of the form taskId_1, taskId_2, taskId_3 (defined in "User Defined Variables") and use them in HTTP Samples (REST requests). When I run postprocessors none of my JSON Extractors or Regular Expression Extractors save the values matched (and I tested the extracted regular expression using RegExp tester.)
The response sent from the GET request that I am parsing looks like (edited for readability):
{
"case-data": {
"Description": "100 parallel tasks",
"Workflow": {
"com.MyCompany": {
"workflow-case-id": null,
"stages": [
{
"stage-guid": "470D2E00-A9E1-11EB-887B-4226FC2CA371",
"tasks": [
{
"task-name": "Stage1Task1P",
"user-group-id": "Joe",
"task-id" : 52
},
{
"task-name": "Stage1Task2P",
"user-group-id": "Joe",
"task-id" : 73
},
{
"task-name": "Stage1Task3P",
"user-group-id": "Joe",
"task-id" : 123
}
]
} ] }}}}
Following the BlazeMeter tutorials, for the Regular Expression Extractor I use
Apply To "Main sample and sub-samples"
Field to check "Response Message"
Name of created variable taskId
Regular expression task-id"\ :\ (.\d+)$
$1$
(I have also tried taskId_1 - my ideal solution would set all the taskId's at once).
For the JSON Extractor that I just tried I use:
Names of created variables: taskId
JSON Path Expressions: $."task-id" (LOG ALL indicates Could not find JSON Path - so I will revise)
Match No: -1
Default Values: taskId not matched
It is as if none of these strings are ever matched so the values are not set - not even default values. I also have a Debug Sample, Debug Postprocessor and a View Results Tree included in the parent Logic Controller - but see no values of variables set anywhere (even in the logs).
I have other JSON extractors that attempt to traverse down the object tree from the top but they also are not setting my User Variables although LOG ALL indicates they are setting the variables of the same name.
What is wrong with my match expressions and assignment parameters?
How can I change my usage of Debug Sampler/Postprocessor/View Result Tree/Properties and variable viewer (which has JMeter variables = True) to observe variables?
Is there a way to run a test plan one step at a time (e.g., a preprocessor, a request, a postprocessor then another postprocessor) by clicking on UI elements?

Regular Expression Extractor:
"task-id"\s*:\s*(\d+)
More information: JMeter Regular Expressions
JSON Extractor:
$..task-id
More information: Jayway JsonPath
To view generated variables just add a Debug Sampler somewhere at the bottom of your script and add View Results Tree listener so Debug Sampler would be in its scope, see How to Debug your Apache JMeter Script for more details.

Related

Storing the output json parameters as variable in jmeter using it in next request

I have a http request which gives json output as :
{
"MESSAGE_CODE":200,
"MESSAGE_DESCRIPTION":"OTP Generated Successfully",
"data":
{
"otp":"123456",
"otpGeneratedDate":"yyyy-mm-dd"
}
}
I want to use otp as the input parameter in json for my next http request.
I have added JSON extractor with following configuration :
enter image description here
Names of created variable : OTP
JSON path expressions : $..data.otp
Match No. : 1
But still when I am calling this parameter as
"otpNumber": "${OTP}" in my next input JSON http request, its not getting called.
and value is passed as ${OTP} for otpNumber
How can I handle this
As per JMeter Documentation:
Variables, functions (and properties) are all case-sensitive
So you need to change this line:
"otpNumber": "${OTP}"
to this one:
"otpNumber": "${otp}"
and your test should start working as expected.
You can observe which JMeter Variables are defined along with their values using Debug Sampler and View Results Tree listener combination.

How to assert a JSON response which have results in random order every time in JMeter?

I am using JSON Assertion to assert if a JSON path exists. Suppose I have a JSON response of an array of 'rooms' that 'contains' an array of cabinets, just like the following example
"rooms":
[
{
"cabinets":
[
{
"id":"HFXXXX",
"locationid":null,
"name":"HFXXXX",
"type":"Hosp"
},
{
"id":"HFYYYY",
"locationid":null,
"name":"HFYYYY",
"type":"Hosp"
},
{
"id":"HFZZZZ",
"locationid":null,
"name":"HFZZZZ",
"type":"Hosp"
}
],
"hasMap":false,
"id":"2",
"map":
{
"h":null,
"w":null,
"x":null,
"y":null
},
"name":"Fantastic Room#3"
}
],
[
{ "cabinets":
[
{
"id":"HFBBBB",
"locationid":null,
"name":"HFBBBB",
"type":"Hosp"
}
],
"hasMap":false,
"id":"3",
"map":
{
"h":null,
"w":null,
"x":null,
"y":null
},
"name":"BallRoom #4"
}
]
I want to Make sure that the 'id' of all the cabinets are correct, therefore I define the JSON path as rooms[*].cabinets[*].id and expect the value to be ["HFXXXX","HFYYYY","HFZZZZ","HFBBBB"]
This works perfectly except that sometimes the values are returned in a different order["HFBBBB", "HFXXX","HFYYYY","HFZZZZ"] instead of ["HFXXXX","HFYYYY","HFZZZZ","HFBBBB"], hence the assertion will fail. The problem is with the order of the returned array and not the values themselves.
Is there a way to sort the order of a response before Asserting and keep using the JSON assertion? or the only way of doing this is extracting the value i want to assert against and use it in JSR223 Assertion (groovy or javascript)?
if that is the case can you show me an example of how I could do it in JSR223 plugin.
I would recommend using a dedicated library, for instance JSONAssert, this way you will not have to reinvent the wheel and can compare 2 JSON objects in a single line of code
Download jsonassert-x.x.x.jar and put it somewhere to JMeter Classpath
Download suitable version of JSON in Java library and put it to JMeter Classpath as well. If you're uncertain regarding what is "JMeter Classpath" just drop the .jars to "lib" folder of your JMeter installation
Restart JMeter so it would be able to load the new libraries
Add JSR223 Assertion as a child of the request which returns the above JSON
Put the following code into "Script" area:
def expected = vars.get('expected')
def actual = prev.getResponseDataAsString()
org.skyscreamer.jsonassert.JSONAssert.assertEquals(expected, actual, false)
It will compare the response of the parent sampler with the contents of ${expected} JMeter Variable, the order of elements, presence of new lines, formatting do not matter, it compares only keys and values
In case of mismatch you will have the error message stating that as the Assertion Result and the full debugging output will be available in STDOUT (console where you started JMeter from)

JMeter Get Body Data before Sending

for example i have http body data like this
{
"signature" : "${signatureCreate}",
"paramA" : "1A02",
"paramB" : "aaa",
"paramC" : "asass"
}
how could i get all params (paramA, paramB, paramC) in my BeanShell Preprocessor? i have to get all these 3, encrypt it, and put it back in "signature" param
i also tries using JSR223 PreProcessor like this (only to try to get the paramA value, but still no luck)
def body = new groovy.json.JsonSlurper().parseText(sampler.getArguments().getArgument(0).getValue())
vars.put("signatureCreate", body.paramA);
thanks in advance
Your code should work fine (given you choose Groovy in the "Language" dropdown), just add Debug Sampler and View Results Tree listener to your Test Plan, you will be able to see signature variable value in the "Response Data" tab of the Debug Sampler
More information: How to Debug your Apache JMeter Script

How to access nested array values in JSON response and use them in a loop in next service in JMeter

I am working on a POST service that give JSON response.
I have to extract certain value from the JSON response. example-
`{
"Result":
{ "Id":22
"StartTime":
"EndTime":
"RoutePoints":
[{ "Id":675,
}
{ "Id":676,
}
]
}
} `
My first part of the question-
How do I refer the "Id" variable inside the "RoutePoint" array using regular expression extractor? I can simply use "Id", but I also have an "Id" variable outside the "RoutePoint" array.
Secondly-
How do I take the "Id" each time and run them in a loop in the following service? Example- I take "Id=675" and perform a job, then take "Id=676" and perform that same job. Please be as detailed as possible, I am new to JMeter.
I would recommend going for JSON Path PostProcessor which is available since JMeter 3.0
Add JSON Path PostProcessor as a child of the request which returns above JSON and configure it as follows:
Variable Names: anything meaningful, i.e. Id
JSON Path Expressions: $..RoutePoints.*.Id
Match Numbers: -1
You should get variables like:
Id_1=675
Id_2=676
Id_matchNr=2
suitable for iteration with i.e. ForEach Controller
Demo:
References:
JSONPath - XPath for JSON
Advanced Usage of the JSON Path Extractor in JMeter

Looping through JSON response + in JMETER

I am using Jmeter for performance testing and stuck at following point:
I am getting a JSON response from Webapi as follows:
PersonInfoList:
Person
[0]
{
id: 1
name: Steve
}
[1]
Person
{
id: 2
name: Mark
}
I need to get the ids based on the count of this JSON array and create a comma separated string as ("Expected value" = 1,2)
I know how to read a particular element using JSON Post processor or Regex processor but am unable to loop through the array and create a string as explained so that I can use this value in my next sampler request.
Please help me out with this: I am using Jmeter 3.0 and if this could be achieved without using external third party libs that would be great. Sorry for the JSON syntax above
Actually similar functionality comes with JSON Path PostProcessor which appeared in JMeter 3.0. In order to get all the values in a single variable configure JSON Path PostProcessor as follows:
Variable Names: anything meaningful, i.e. id
JSON Path Expressions: $..id or whatever you use to extract the ids
Match Numbers: -1
Compute concatenation var (suffix _ALL): check
As a result you'll get id_ALL variable which will contain all JSON Path expression matches (comma-separated)
More "universal" answer which will be applicable for any other extractor types and in fact will allow to concatenate any arbitrary JMeter Variables is using scripting (besides if you need this "expected value and parentheses)
In order to concatenate all variables which names start with "id" into a single string add Beanshell PostProcessor somewhere after JSON Path PostProcessor and put the following code into "Script" area
StringBuilder result = new StringBuilder();
result.append("(\"Expected value\" = ");
Iterator iterator = vars.getIterator();
while (iterator.hasNext()) {
Map.Entry e = (Map.Entry) iterator.next();
if (e.getKey().matches("id_(\\d+)")) {
result.append(e.getValue());
result.append(",");
}
}
result.append(")");
vars.put("expected_value", result.toString());
Above code will store the resulting string into ${expected value} JMeter Variable. See How to Use BeanShell: JMeter's Favorite Built-in Component article for more information regarding bypassing JMeter limitations using scripting and using JMeter and Java API from Beanshell test elements.
Demo:

Resources