Looping through JSON response + in JMETER - 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:

Related

Extract value with applied condition in jmeter using regular expression Extractor

I want to extract every text message where nickname is Mack Dack. how can i do that using regularExpression extractor
{"messages":[{"from":{"nickname":"Mack Dack","participantId":2,"type":"Agent"},"index":2,"type":"ParticipantJoined","utcTime":1600262148000},{"from":{"nickname":"Mack Dack","participantId":2,"type":"Agent"},"index":4,"text":"Starting the bot: ToBi","type":"Message","utcTime":1600262151000},{"from":{"nickname":"Sonaltest Garg","participantId":1,"type":"Client"},"index":5,"text":"Starting the bot: ToBi","type":"Message","utcTime":1600262161000},{"from":{"nickname":"Mack Dack","participantId":2,"type":"Agent"},"index":7,"text":"Welcome! I am Watson. How can I help?","type":"Message","utcTime":1600262163000},{"from":{"nickname":"Sonaltest Garg","participantId":1,"type":"Client"},"index":8,"text":"Welcome! I am Watson. How can I help?","type":"Message","utcTime":1600262174000}],"chatEnded":false,"statusCode":0,"alias":"118","secureKey":"a20dfd835cd8d2199017","userId":"00765F620FFE00A2","chatId":"000BEaFP3FBS003W","nextPosition":9}
my purpose is to select only those text message which are coming from mack dack and compare them with my local json file if both message are same then send message which is same by Sonaltest Garg
Using regular expressions for parsing JSON is not the best idea, normally you should rather be using JSON Extractor but in particular your case you won't be able to get benefits of JsonPath as when it comes to JSON Arrays querying parent attributes using children as filter is not possible.
So I would rather recommend using JSR223 PostProcessor and the following Groovy code:
def messages = com.jayway.jsonpath.JsonPath.read(prev.getResponseDataAsString(), '$..[?(#.type == "Message")]')
messages.findAll { message ->
message.from.nickname == 'Mack Dack'
}.eachWithIndex { message, index ->
vars.put('message_' + (index + 1), message.text)
}
As the result you will get the following JMeter Variables:
message_1=Starting the bot: ToBi
message_2=Welcome! I am Watson. How can I help?
Check out Top 8 JMeter Java Classes You Should Be Using with Groovy article to learn what these prev and vars shorthands mean

Extracting a value from jmeter response and exporting it to a csv file

I need to know how can I extract a value from response in jmeter and export it to a csv file.
Suppose my response is like this:
<ns3:UpdateConsumerResponse
xmlns:ns3="http://Pandora.NextGenCRM.Integrations.UpdateConsumerResponse"
xmlns:ns0="http://tempuri.org/"
xmlns:ns1="http://schemas.datacontract.org/2004/07/Pandora.Xrm.DataModel.Request"
xmlns:ns2="http://schemas.datacontract.org/2004/07/Pandora.Xrm.DataModel.Response">
<MasterConsumerID>
CRM-CONID-000000519344
</MasterConsumerID>
</ns3:UpdateConsumerResponse>
I need to extract the master consumer value and export it to an csv file.
First of all you have to add an regular expression extractor as a child of this request
and then mention below inputs
1.Reference Name: MasterConsumer (or any variable)
2.Regular expression: abc(.*?)d (suppose your value is like abcCRM-CONID-000000519344d
then provided reg ex will work, now replace abc with your left
boundary and d with right boundary which you can get from your response. if still you need more help then
please provide this value along with more text from both side )
3.Template: $1$
4.Match No:1
5.Default Value: null
now you have your value stored in MasterConsumer variable (apply debug sampler to verify). Just you need to write into csv file, so add beanshell post processor as a child of same request and write below code for printing data into csv file
MasterConsumer =vars.get("MasterConsumer");
f = new FileOutputStream("Path"-Output.csv",true);
p=new PrintStream(f);
this.interpreter.setOut(p);
p.println(MasterConsumer);
f.close();
Add XPath Extractor as a child of the request, which returns above value
Configure it as follows:
Check Use Namespaces box
Reference Name: anything meaningful, i.e. ID
XPath query: /ns3:UpdateConsumerResponse/MasterConsumerID/text()
Add Beanshell PostProcessor after the XPath Extractor
Add the following code into the PostProcessor's "Script" area:
import org.apache.commons.io.FileUtils;
String file = "path_to_your_file.csv";
String ID = vars.get("ID");
String newline = System.getProperty("line.separator");
FileUtils.writeStringToFile(new File(file),ID + newline, true);

Need to extract dynamic values from a string response in Jmeter

I need to extract the dynamic value "BSS1,DS1,HYS1,MS1,PTS1,QS1,USG1,YS1,RT10086,RT10081,RT10084,RT10082,OT10076,RT10083,UT10081,RT10085,"
from the string response "ACCOUNT_DETAIL_ACCOUNT_PRODUCT_SERVICES_EDIT_UPDATE_NameSpace.grid.setSelectedKeys(["BSS1","DS1","HYS1","MS1","PTS1","QS1","USG1","YS1","RT10086","RT10081","RT10084","RT10082","OT10076","RT10083","UT10081","RT10085"]);"
I have tried using the regular expression extractor :
Regular Expression :Keys\(\[\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\",\"(.+?)\"]\)
template : $1$$2$$3$$4$$5$$6$$7$$8$$9$$10$$11$$12$$13$$14$$15$$16$
But the above regular expression works only if there are 16 values in the response. If the response contains less number of values, for example, "ACCOUNT_DETAIL_ACCOUNT_PRODUCT_SERVICES_EDIT_UPDATE_NameSpace.grid.setSelectedKeys(["BSS1","DS1"]);"
then the above regular expression doesn't work.
How can I extract the values in the response if the total count is unknown?
Also the double quotes in the response need to be omitted.
Is there any post processor using which dynamic values can be extracted?
Any help is greatly appreciated.
I believe it will be easier with some scripting.
Add Beanshell PostProcessor as a child of the request which returns aforementioned response
Put the following code into the PostProcessor's "Script" area:
String response = new String(data);
String rawKeys = response.substring(response.indexOf("[") + 1, response.indexOf("]")); // get the data inside square brackets
String keysWithoutQuotes = rawKeys.replaceAll("\"", ""); // remove quotes
String[] keyData = keysWithoutQuotes.split("\\,"); // get array of keys
for (int i = 0; i < keyData.length; i++) { // store array of keys into JMeter variables like
vars.put("Keys_" + (i +1), keyData[i]); // Keys_1=BSS1, Keys_2=DS1, etc.
}
vars.put("Keys_matchNr", String.valueOf(keyData.length)); // set Keys_matchNr variable
Where:
data is byte array containing parent sampler's response data
vars is a shorthand to JMeterVariables class which provides read/write access to JMeter Variables.
As a result you'll have variables like:
Keys_1=BSS1
Keys_2=DS1
..
Keys_matchNr=X
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for additional information on Beanshell scripting in JMeter and some more examples

How to post the exact number of values which are retrieved from post processor?

I'm landing into a page where some Customers listed out. I'm retriving all the Customer Ids by Regular Expression Extractor Post-Processor.
Now, in a subsequent request I need to pass those Ids. It's being passed as a 'Body Data' by the following format:
[19327,15947,14421,18813,20942]
Let say, there are 5 Customer Ids retrived, then I can use the variables for each record as follows:
Passing Variables: [${CustomerId_1},${CustomerId_2},${CustomerId_3},${CustomerId_5}]
Posting Variable Values: [19327,15947,14421,18813,20942]
But let say, there are only 3 Customer Ids retrived, and if I pass the variables as above then the sampler will fail because currently it just retrived 3 Customer Id records.
Passing Variables: [${CustomerId_1},${CustomerId_2},${CustomerId_3},${CustomerId_5}]
Posting Variable Values: [19327,15947,14421,${CustomerId_4},${CustomerId_5}]
How to deal with this issue, plz. do help.
Thanks in advance
Add Beanshell PreProcessor as a child of your 2nd request
Put the following code into the Pre-Processor's "Script" area
int customers = Integer.parseInt(vars.get("CustomerId_matchNr"));
StringBuilder requestBuilder = new StringBuilder();
requestBuilder.append("[");
for (int i = 1; i <= customers; i++) {
requestBuilder.append(vars.get("CustomerId_" + i));
if (i != customers) {
requestBuilder.append(",");
}
}
requestBuilder.append("]");
sampler.getArguments().getArgument(0).setValue(requestBuilder.toString());
The above code will build required request line depending on number of matches and automatically set request body.
Referenced classes:
vars - shorthand to JMeterVariables
sampler - provides access to the parent sampler, in case of HTTP Request it will be HTTPSamplerProxy
StringBuilder - comes with Java SDK
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for more information on Beanshell scripting, explanation of pre-defined variables and some useful examples.
refName_matchNr will return the number of matches. So in your case CustomerId_matchNr will give you number of customerIDs.
Use a beanshell pre-processor to run a loop and construct the BodyData string and save it to a new variable, use that variable in your subsequent sampler.

Jmeter extract data using BeanShell PreProcessor and add parameters

Having the following request:
From this I extract using the Regular Expression Extractor the following string:
%5B1172%2C63%2C61%2C66%2C69%2C68%5D
I decode this using the urldecode function: ${__urldecode(${Groups_g2})}
Decoded: [1172,63,61,66,69,68]
On the following request I want to extract the values using the BeanShell PreProcessor to obtain a list of parameters like this one:
I know that I have to use sampler.addArgument but i can't figure how to extract data from the list and add the values as parameters.
Try the following:
Put ${__urldecode(${Groups_g2})} into Beanshell PreProcessor's Parameters input field
Enter the following code into Script area
String params = Parameters.substring(1, Parameters.length() - 1); // remove square brackets
int counter = 1;
for (String param : params.split(",")) {
sampler.addArgument("parameter" + counter, param);
counter++;
}
I have no idea what parameter names need to look like, hopefully above information will be helpful.
HTTP Request with no parameters:
Beanshell PreProcessor
Parameters in View Results Tree Listener
For more information on Beanshell scripting in Apache JMeter check out How to use BeanShell: JMeter's favorite built-in component guide.

Resources