Extract value with applied condition in jmeter using regular expression Extractor - jmeter

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

Related

Extracting corresponding values in JSR223 post processor in JMeter Randomly

Hi All / Dimitri T Could you please post your valuable thoughts on extracting corresponding Values (For example ItemID1 and ItemSlot1) in one block of code randomly. I was able to write below Jsr223 postprocessor code and it is working fine. But when there are Blank spaces in ItemSlot id, then they are not fetching. From below code , i am passing ${rannum} under "Match No" in required regular expression.
Note: There will be more than 100 corresponding values. In some cases, we won't have ItemSlot1.i.e Blank/null values are appearing from server response. Hence, my script is not picking corresponding values.
Application Server Response:
"viewSaleListingLink": "https://Example.com/cars/item/search/-/listing/ItemID1/100011142",
"saleCountry": "",
"saleNote": "",
"bidLiveUrl": "https://Example.com/cars//registration?p_p_id=RegistrationPortlet_WAR_PWRWeb&p_p_lifecycle=1&p_p_state=normal&ItemSlot1=103009468",
JSR223PostProcessor Code
import java.math.MathContext;
import java.math.RoundingMode;
// Read occurance values from pervious response
def Max = Integer.parseInt( vars.get("ItemID1_matchNr"));
int min=1;
int rannum = min + (int) (Math.random() * ((Max - min) + 1));
log.info("Values id ="+rannum);
vars.put("rannum",rannum.toString());
enter image description here
If you need to extract a random match/pair of matches from the response using Regular Expression Extractor - it's sufficient just to provide 0 as the "Match No" and it will automatically fetch the random match group so you won't have to write any code:
Also be aware that Post-Processors are executed in the order they appear (upside down) so:
If your JSR223 PostProcessor is above the Regular Expression Extractor - ItemID1_matchNr will be undefined
If your JSR223 PostProcessor is below the Regular Expression Extractor - your rannum variable won't have any value
Also your response seems to be JSON so it makes sense switching to JSON JMESPath Extractor which is more powerful and convenient

Jmeter - How to handle duplicate values captured in RegExpression from the same response

How to ensure/handle duplicate values are not getting captured while using regular expression?
In my scenario i need to capture multiple offers from my response. But cant use the same offers again and again within the transaction
There are multiple ways to do this. If you are using the default Regular Expression Extractor, the problem is it creates the variables (eg: offer_1, offer_2 etc), ready to go with the execution. It would've been easier if it returned a ArrayList of some sort where we can remove the duplicates. What I am about to suggest is to add those variables to a list in a JSR223(groovy) sampler/post processor then convert them back to usual jmeter variables to use in the usual jmeter script flow.
Snippet:
I created a sample script as per your description which would return multiple offers with some duplicates. Following is the state of jmeter variables before post processing.
offer_1=RUSSIA
offer_1_g=1
offer_1_g0=offer="RUSSIA"
offer_1_g1=RUSSIA
offer_2=UK
offer_2_g=1
offer_2_g0=offer="UK"
offer_2_g1=UK
offer_3=ICELAND
offer_3_g=1
offer_3_g0=offer="ICELAND"
offer_3_g1=ICELAND
offer_4=USA
offer_4_g=1
offer_4_g0=offer="USA"
offer_4_g1=USA
offer_5=UK
offer_5_g=1
offer_5_g0=offer="UK"
offer_5_g1=UK
offer_6=USA
offer_6_g=1
offer_6_g0=offer="USA"
offer_6_g1=USA
offer_7=USA
offer_7_g=1
offer_7_g0=offer="USA"
offer_7_g1=USA
offer_matchNr=7
As you can see above there are duplicates in the variables. Put the following Groovy code in a JSR223 post processor with groovy as language selected.
// Count of offers extracted by Regular Expression Extractor
def count = Integer.parseInt(vars.get("offer_matchNr"))
// An empty list which will store the offers
def offer_list = []
for (int i = 1; i <= count; i++){
def offer = vars.get("offer_" + i)
offer_list.add(offer)
}
// Removes the duplicates in the list
offer_list.unique()
// Following one liner adds new variables but with only unique offers in similar format as jmeter variable.
offer_list.eachWithIndex{ it, index -> vars.put("unique_offer_${index+1}", "${it}")}
After post processing:
unique_offer_1=RUSSIA
unique_offer_2=UK
unique_offer_3=ICELAND
unique_offer_4=USA

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:

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.

JMeter: Parse JSON and count

I am using JMeter to test a web application. The application returns JSON that looks like the following:
{"type":"8","id":"2093638401"}
{"type":"9","id":"20843301"}
{"type":"14","id":"20564501"}
I need to get a count based on type.
I have tried adding foreach controller with a regular expression extractor, but Im not sure I have done it correctly:
Apply to: Main sample only
Response field to check: Body
Reference name: match_type
Regular Expression: "type":"(\d)"
Template: $1$
Match no.: -1
Im new to JMeter so Im not sure if Im doing any of this correctly.
Thanks
If you want to operate on both type and id in single sampler, I think simple regex and ForEach controller won't be sufficient. You will have to write two regex extractor followed by while controller with BSF processor (javascript or beanshell) to extract both the values and export them to jmeter variable. Something of following type
- First Request
- Regex extractor for type
- Regex extractor for id
- BSF processor (to initialize the loopcount=0 and the total_matches of matches that you found)
- while controller (loopcount < total_matches)
- BSF processor
- export/set current_type = type_$loopcount
- export/set current_id = id_$loopcount
- increment loopcount
- USE current_type and current_id in whatever sampler you like
== Update ==
This http://goo.gl/w3u1r tutorial depicts exactly how to go about it.

Resources