JMETER : While condition is failing with syntax error - jmeter

I have a scenario where in I need to wait for the response text .I need to send the same request till i get the required response text. I included my http samples in while loop with a counter. Now I am not able get the correct while condition.
Tried with below conditions.
${__javaScript(("${recordTypeLabel1}"!="asdf" && ${counter} < 5),)}
${__jexl3("${recordTypeLabel1}" != "asdf",)}
Both are failing. How to handle this?
Pleasae help.
Threadgroup
Once only controller Login
loop controller
HTTP req
HTTP req
While loop {
Counter
HTTP request
HTTP Request
JSON extractor
}
HTTP req
Once only Controller Logout

The correct syntax for the __jexl3() function would be:
${__jexl3("${recordTypeLabel1}" != "asdf" && ${__jm__While Controller__idx} < 5,)}
Don't use __javascript() function as it is some form of a performance anti-pattern, stick to __jexl3() or __groovy() functions if you need to script some extra logic
Also you don't need to introduce a Counter, since JMeter 5.0 you have a special pre-defined variable called ${__jm__While Controller__idx} which holds zero-based iteration number of the While Controller. (If you change the While Controller's label to something else - make sure to amend the variable accordingly)
Exit when loop number exceeds the threshold
Exit when variable value becomes expected:

Related

Jmeter - How to tell loop controller to loop for all the numbers from 0000 -> 9999 && and exit once status code 200 is being reached?

I have a scenario where I need to loop for all the numbers from 0000 to 9999, and once reached status code 200, to exit the loop.
My script looks like:
If I put the static number into Loop controller works fine
But: How to lead Loop controller based on the counter element && exit the loop once status code 200 is being reached?
You can do this on one shot using While Controller and the following __groovy() function:
${__groovy(vars.put('counter'\, new java.text.DecimalFormat('0000').format(Double.parseDouble(vars.get('__jm__While Controller__idx') ?: 0))); vars.get('counter') != '0005' && ctx.getPreviousResult().getResponseCode() != '200',)}
No other test elements/loops/whatever are required
Option 1
You can exist a loop control when a condition is satisfied with an If controller and a Flow Control Action.
Set following in the IF controller
${JMeterThread.last_sample_ok}
2. Set Break Current Loop in the Flow Control Action
Note: You shall add a delay after checking the status of the last sampler. This can be achieved with a Constant Timer
Option 2
You could achieve this with a JSR223 Post-processor too.
Add a JSR223 Postprocessor to your HTTP Request
Add the following into the script window
if (vars.get("JMeterThread.last_sample_ok").toBoolean()){
ctx.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.BREAK_CURRENT_LOOP )
}
API Documentation : Test Logical Action, JMeter Context
Option 3
Add Results Status Action Handler Postprocessor to the HTTP Request and set Break Current Loop

I need a particular number of "success" in response data by sending the same request

I am getting a text in the response data "success". i am using while controller with a http request, counter, regx. regx is capturing the text, counter is to increment the count. and i want the while controller to run until i get say 5 times success in the response data
while controller ${__jexl3("${variable}" ="Successful" && ${counter} = 5)}
http request
regx
counter
it became an infinite loop
the equality operator in JEXL is "==" (you see section "Operators" in documentation: http://commons.apache.org/proper/commons-jexl/reference/syntax.html), besides the while loop should go until the counter variable is less equal to 5. So the condition should be set like this:
while controller ${__jexl3("${variable}" == "Successful" && ${counter} <= 5)}
i hope this helps
I have added a regular expression with reference name variable to capture the word "successful "from response data and match no as -1 .
And in while controller
Condition = ${__javaScript("${variable_matchNr}" =="${counter}",)}
And added http request (with same regx)and pause
It worked.
Thanks .

In JMeter, How do i loop until a result is found

I have a request in Jmeter that I need to loop until I find the result I am looking for. I have read a few bits about a while controller but found them unhelpful as they seem to glance over vital information or are using an older version of Jmeter
I'm currently using Jmeter 5.0, and I have attempted to implement a while controller but failed as I think I do not understand how to properly handle the response, or even grab it, and then use it as a comparison to assert if the item exists.
I get a response from the HTTP request call response that looks a little somthing like this:
{"data":{"getIDs":{"Page": 1,"PageSize": 25,"PageCount": 1,"isFirstPage": true,"batches":[{"id":"b601a257-13fe-4de3-b779-a5922e89765a"},{"id":"b601a257-13fe-4de3-b779-a5922e89765b"},{"id":"b601a257-13fe-4de3-b779-a5922e89765c"}]}}
I need to recall the endpoint until I have found the ID I am looking for or cancel after 10 attempts
So after a bit of fumbling around I, I figured on my own answer that seems to work well. But I would suggest looking at other sources before taking mine as gospel.
The basic structure looks as follows:
Within a thread I set the variables then create the while loop as the next step. Within the While loop I created a counter then added the request I wanted to loop after. To make the loop work for me, I have three items sat under the request.
A Response Assertion: this check for a 200 status as the call should never fail
A Constant Timer: There is a delay between polls of the end point
A JSR223 Assertion: groovy code used ensure the while loop logic is handled
User Defined Variables:
Here i have setup two variables:
DONE: Done is a string value I alter if my JSR223 Assertion finds the values I'm looking for in the HTTP request
MyValue (this is dynamically driven in my actual test, for demo purpose, I’m just declaring a value to look for i.e. 12345)
While Controller:
I still feel i may not understand this correctly, however after some googling I came across the following code that works for me despite some errors in the JMeter console:
${__javaScript(("${DONE}" != "yep" && ${Counter} < 10),)}
This code is saying that the while loop will continue until either of these two conditions are met:
DONE, the variable created earlier, is equal to the value yep
Counter is less than 10 (Counter is declared beneath the while loop)
Counter:
this was a simple configuration step that just worked once I understood it needed to be within the while loop, i configured the following:
Starting value = 1
Increment = 1
Exported Variable Name = Counter
Ticked 'Track Counter independently for each user'
Ticked 'Reset counter on each thread group iteration'
(Exported Variable Name: you can call this whatever you want, I’ve named it counter for the purpose of this demo)
JSR223 Assertion:
This is a simple script assertion that just uses a Boolean and a couple of if statements to assert the state of the test.
import org.apache.commons.lang3.StringUtils;
def done = vars.get("DONE");
String response = prev.getResponseDataAsString(); //retrieves the http request response as text
String MyValue = vars.get("MyValue");
def counter = vars.get("Counter");
//Find Substring within response string and stor result as boolean
String container = response;
String content = MyValue;
boolean containerContainsContent = StringUtils.containsIgnoreCase(container, content);
//Check if the true condition is met and change the value so the loop exits
if (containerContainsContent == true){
log.info("------------------------Got Here");
vars.put("DONE", "yep");
}
//Force test to fail after 10 loops
if (Counter.toString() == "10"){
assert 1 == 2
}

how to Bypass the Sampler based on previous response value in jmeter?

I have caught up in a situation, where in i need to verify the response of the Previous Sampler for one of the value and if the Value for that is [], then i need to trigger the below request or else then switch to another Sampler.
Flow:
Check Response of Sampler for One of the attribute
IF(attribute value==[])
Execute the Sampler under IF Conditions.
ELSE
New Sampler
Sample Response:
{"id":8,"merchant_id":"39","title":"Shirts-XtraLarge","subtitle":null,"price":110,"description":null,"images":"image_thumbs":[[]],"options":[],"options_available":[],"custom_options":[]}
I need to check if the attribute custom_options is empty or not! If Empty do some actions and if not empty do some other action !
Need if condition to simulate this!
Help is useful!
A nice to have feature in JMeter would be Else statement, but until then you will have to use 2 If Controllers
If Controller allows the user to control whether the test elements below it (its children) are run or not.
Assuming you hold your attribute value using regex/json/css/other post processor extractor add two condition, first is positive and under it the Sampler:
${__groovy("${attributeValue}" == "[]")}
Second is negative and under it add the New Sampler
${__groovy("${attributeValue}" != "[]")}
__groovy is encourage to use over default Javascript
Checking this and using __jexl3 or __groovy function in Condition is advised for performances
Go for Switch Controller
Add JSR223 PostProcessor as a child of the request which returns your JSON
Put the following code into "Script" area:
def size = com.jayway.jsonpath.JsonPath.read(prev.getResponseDataAsString(), '$..custom_options')[0].size()
if (size == 0) {
vars.put('size', 'empty')
} else {
vars.put('size', 'notempty')
}
Add Switch Controller to your Test Plan and use ${size} as "Switch Value"
Add Simple Controller as a child of the Switch Controller and give empty name to it. Put request(s) related to empty "custom_options" under that empty Simple Controller
Add another Simple Controller as a child of the Switch Controller and give notempty name to it. Put request(s) related to not empty "custom_options" under that notempty Simple Controller.
More information: Selection Statements in JMeter Made Easy

I want to check if a response attribute of one http request exits in another http request as well. How can I do that?

HTTP request
.. regular expression to pick up a token "PostID"
HTTP request
..Beanshell assertion to verify if ${PostID} exists in the response
I am using the while controller to loop the request till PostID is found
while condition being ${__javaScript("${count}" != 1)}
Beanshell assertion is failing though I see the PostID in the response of "FetchSentPost" request
I need the while loop to end on the first encounter of Post ID in the HTTP request "FetchSentPost"
Where Am I going wrong?
You have a syntax error in your Beanshell script:
String ID = vars.get(PostID);
^^^^^^
should be
String ID = vars.get("PostID");
Going forward you can add debug(); directive to the beginning of your JMeter script for troubleshooting. I would also recommend switching to JSR223 Assertion and Groovy language, Groovy performs much better and more Java-compliant.
There are several mistakes made in the script.
Condition must be changed to ${__javaScript(${count} != 1)}. No double quotes.
In BeanShell Assertion, instead of count += 1, you must assign count value using vars.put as follows vars.put("count", 1);
As Dmitri mentioned, other mistake is:
String ID = vars.get("PostID");
Related to contains vs regex matching, try both after making above changes. I tried with contains, it is working.
Using contains:
while(!str.contains(ID)){
vars.put("count", 1);
}
created a user defined variable 'PostIdFound' with value 'False' outside the while loop.
Changed the while condition to ${__javaScript(${PostIdFound} != true)}
and then changed the BeanShell script as follows
import java.util.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
String ID = vars.get("PostID");
String str= SampleResult.getResponseDataAsString();
vars.get("PostIdFound");
if(str.contains(ID)){
vars.put("PostIdFound","true");
}
Issue Resolved. Thankyou #Dmitri T and #Naveen for the help

Resources