How to implement If Else block in Jmeter test plan? - if-statement

I have a task where I need to perform two tasks based on the previous Sampler result.
If Assertion fails
{
send email with the error message.
}else
{
perform the tasks in while controller.
}
I have achieved the first part easily by providing the condition in If controller ${JMeterThread.last_sample_ok} == false
I have problems going to else block. I have tried two IF controllers but with no success.
Case here is need to perform one task only either IF block or Else block. But In my case it goes to both the blocks and perform both the tasks.
Can anyone help how to achieve this?

There is no "Else" block in JMeter, you have only "If" therefore if you need "Else" behavior you need to use 2 IF Controllers with opposite conditions.
But, for 2nd If Controller you won't be able to use this as this ${JMeterThread.last_sample_ok} variable will be overwritten with the result of your SMTP Sampler so if your SMTP Sampler will be successful ${JMeterThread.last_sample_ok} variable will become true therefore second If Controller will be executed as well.
So I would recommend the following approach:
If your Assertion Fails
In Beanshell PreProcessor define a custom variable like:
vars.put("run_while_controller", "false");
Put your While Controller under another If Controller and use ${run_while_controller} as a condition
Alternative option is stopping the test after sending an email, this can be done using i.e. Test Action sampler
Going forward I would suggest using Debug Sampler and View Results Tree Listener to double check all the JMeter Variables values, this is most convenient way to see all JMeter variables and properties values. See How to Debug your Apache JMeter Script article for more information on getting to the bottom of your JMeter test unexpected behavior.

Related

Jmeter beanshell - Error invoking bsh method:eval when trying to clear cookie/cache

I am trying to clear cookie and cache in the middle of a thread group, so that I could login to the test application with another user. I wrote the following beanshell in jmeter.
import org.apache.jmeter.protocol.http.control.CookieManager;
CookieManager manager = ctx.getCurrentSampler().getProperty("HTTPSampler.cookir_manager").getObjectValue();
ObjectValue();
clear cache.clear();
I got the below error in my jmeter logs.
Error invoking bsh method:eval
Sourced file: inline evaluation of: "import org.apache.jmeter.protocol.http.control.CookirManager; ..." Token Parsing error; Lexical error at line 3, column 59. Encountered: "\u201c" (8220), after: ""
I tried to use the JSR223 post processor to clear cache using the below code:
sampler.getCacheManager().clear();
sampler.getCookieManager().clear();
But the above piece of code is acting as a global one, and starts clearing the cache and cookie for every sampler for the reminder of the script, which is causing authentication issues.
Please let me know if there's any other method to clear cache and cookie at a particular instance/sampler alone.
Is there any particular .jar to be imported to Jmeter to make this work?
There is a syntax error in your script, it's not possible currently to say where exactly because your code is not full. I don't see any problems with it apart from a typo in the property name which should look like HTTPSampler.cookie_manager
Since JMeter 3.1 you're supposed to use JSR223 Test Elements and Groovy language for scripting
JSR223 PostProcessor obeys JMeter Scoping Rules so if you place it as a child of a particular Sampler - it will be applied to that Sampler only.
If you put it at the same level as several Samplers - it will be applied to all of them.
Wouldn't it be easier to untick "Same user on each iteration" box in the Thread Group?

JMeter IF-condition check

In client-side script 1st user creates events in a calendar for 2nd user, 2nd user accepts/declines them.
I would like to exclude possible errors during event creation and check if event request was created before 2nd user tries to accept it using xpath built on event request template like:
EventRequest_SubjectN
(N is iteration number of event request in a cycle, so if event request N wasn't created by 1st user, 2nd user action with event N fails).
Between these actions are another actions of both users, by this reason I can't use ${JMeterThread.last_sample_ok}.
Is there any analog of this function, but for necessary/specific action several steps ago, not for last sample?
What is the best way to organize IF-condition is that case?
I think about to add BeanShell PostProcessor after 1st user Event request N with a code like:
var rc = prev.getResponseCode();
if(rc.equals("200")){
vars.put('EventRequest_Subject_${N}', 'EventRequest_Subject_${N}');
}
and use not null condition for EventRequest_Subject_${N} in IF-controller for 2nd user.
But it doesn't work in this way. Where am I wrong?
UPD. Solution:
Tried 3 ways:
if Event_RequestN created - put into variable specific value, then use it in IF-condition before 2nd user action with Event_RequestN;
add action with specific assertion before 2nd user action with Event_RequestN and use ${JMeterThread.last_sample_ok} in IF-condition;
add action with xpath extractor before 2nd user action with Event_RequestN and use ${_isVarDefined(EventRequest_Subject${N}_FOUND)} in IF-condition;
and ended up with 3rd variant as the best on practice.
Don't use Beanshell, since JMeter 3.1 you're supposed to be using JSR223 Test Elements and Groovy language for scripting
Don't inline JMeter Functions or Variables into scripts, go for code-based equivalents instead
As per JMeter Documentation
Properties are not the same as variables. Variables are local to a thread; properties are common to all threads
so if you want to share a piece of data between 2 threads (virtual users) you need to use props, not vars
It's easier to implement your scenario using Inter-Thread Communication Plugin

Jmeter: unable to use multiple conditional statements in If Controller

ANSWER TO THE QUESTION
Please, dear reader, if you wish, you can proceed further and read through the question. But at the most top I'm willing to provide Dmitri's answer, so that others won't waste time playing around with Jmeter If Controller.
If you wish to use multiple condition statement in If Controller,
specifically if you want to check that variables equal some strings,
DON'T USE ${__javaScript()} FUNTION!!! Dmitri suggested to use instead
${__groovy()} function, which worked in my situation. Correct syntax
below. Pay attention to opening parenthesis, comma location and closing curly brackets:
${__groovy((vars.get('yourVariable').equals('someString') &&
vars.get('yourAnotherVariable').equals('someOtherString')),)}
Addition
If you want to save your time while trying to make If Controller working with multiple conditions, always uncheck Interpret Condition as Variable Expression checkbox. Otherwise you will have to stuck with those __javaScript, __groovy or other functions, as there is no way to understand how the hell they suppose to work and why they don't resolve to true or false (log file is always clean at this situation). This is how you do without help of those "functions". Please see my example below
${yourVariable} != 'not_found' && ${youAnotherVariable_matchNr} == 1
That's it, no need to use any functions.
INITIAL QUESTION
In Jmeter v4.0 r 1823414 I can use If Controller only with single statement, but not with multiple. Example of using multiple statements I have taken from here and it was suggested to use
${__javaScript("${responsecode}"=="404")} &&
${__javaScript("${responseMessage}" == "Not Found")}
I have also checked blazemeter tutorial page, but it says nothing about multiple conditional statements inside If Controller.
Example of my Test Plan is below
In my Debug Sampler I can see following
At some place in the Test Plan I put IF Controller to check that both variables are equal to not_found...
${__javaScript(vars.get('manual_bug')=='not_found')} && ${__javaScript(vars.get('integration_bug')=='not_found')}
...so all the subsequent actions are executed. However, this IF Controller either never gets executed or always return FALSE. Not sure what's happening with it.
Before blaming me :-) that I didn't do enough research and rushed to ask a question on SO, I will provide below samples of what I've already tried and that didn't help:
With double quotes around variables
${__javaScript(vars.get("manual_bug")=="not_found")} && ${__javaScript(vars.get("integration_bug")=="not_found")}
With additional space between equal sign
${__javaScript(vars.get('manual_bug') == 'not_found')} &&
${__javaScript(vars.get('integration_bug') == 'not_found')}
Avoid using vars.get
${__javaScript(${manual_bug} == 'not_found')} && ${__javaScript(${integration_bug} == 'not_found')}
Using double quotes without vars.get
${__javaScript(${manual_bug} == "not_found")} && ${__javaScript(${integration_bug} == "not_found")}
My log file looks completely fine, no errors
Please advise if someone was able to execute multiple conditional statements in the Jmeter tool? Thanks!
In the link you're referencing the 2 clauses are in a single __javaScript() function and you have 2 different functions so JMeter doesn't know what does your && means especially given Interpret Condition as Variable Expression? default mode of the If Controller.
Also if you open If Controller GUI you will see the following warning:
For performance it is advised to check "Interpret Condition as Variable Expression"
and use __jexl3 or __groovy evaluating to true or false or a variable that contains true or false.
${JMeterThread.last_sample_ok} can be used to test if last sampler was successful
Therefore I would recommend reconsidering your approach and use __groovy() function, the relevant syntax would be:
${__groovy((vars.get('responseCode').equals('404') && vars.get('responseMessage').equals('Not Found')),)}
Demo:
The following syntax (with double quotes) works too, however it also requires that you uncheck the 'Interpret Condition as Variable Expression' setting.
"${yourVariable}" != "not_found" && "${youAnotherVariable_matchNr}" == "1"

How to write Bean Shell Script to compare two variables and print the output. JMETER

I have two variable 1)Expected(taken from excel file) & 2)Actual(regex from result)
Now i tried to compare both the variables using bean Shell Post processor Scripting.
if(("${Expected}").equals("${Actual}"))
{
IsSuccess = true;
}
else
{
IsSuccess = false;
}
which should actually mark sample as pass and fail according to the comparison.
But i can't find the sampler marked fail when the comparison returns false.
Is their any error in my condition.
Also Please help to print output to console
Help is appreciated.
Thank You
Don't inline JMeter Variables or Functions into a Beanshell (or any other) script, they might resolve into something which will cause compilation failure
If you want to mark sampler as passed or failed from the Post-Processor you should be doing it a little bit differently
Example suggested code:
if (vars.get("Expected").equals(vars.get("Actual"))) {
prev.setSuccessful(true);
}
else {
prev.setSuccessful(false);
}
Other recommendations:
Going forward consider switching to JSR223 PostProcessor and Groovy language as Groovy performance is much higher for any scripting implementations
You can achieve the same without having to write a single line of code via "normal" Response Assertion, example configuration would be something like:
See How to Use JMeter Assertions in Three Easy Steps article for more information on conditionally passing/failing your JMeter samplers using assertions.

jMeter - If Controller is only executed if it contains a sampler?

I'm having trouble with the If Controller in jMeter.
I have a thread group. Inside the thread group is a loop controller. Each time the loop executes, it runs an HTTP sampler.
I want to trigger the If Controller based on the response of this sampler.
However, the If Controller only seems to trigger if it contains another sampler.
But I don't want it to contain a sampler. The steps to be executed when it triggers are a JSON Path Extractor and a Beanshell PostProcessor. These are used to extract part of the JSON in the response from the existing sampler and then use this value to update a shared hashmap in the Beanshell PostProcessor. But they won't run without a sampler present inside the If Controller. And if I put a sampler in there, of any description - even a dummy one, the response data from the first sampler is lost and I can't get to the JSON response from it any more - and the test is then broken.
Any idea how to get round it?
I've tried adding blank listeners and things like that but they don't cause the If Controller to trigger. The only thing that does is a sampler which then breaks my test sequence.
An If Controller is not allowed as a child of the first sampler.
Yes, the jmeter internals work only with samplers. So to run a post-processor in some scope (your IF controller creates the scope), you need a sampler inside it. All the post-processors/timers/listeners etc are actually attached to the samplers of their scope. It is important thing to know about JMeter.
To achieve your goal, you can do a trick where you attach the Regexp extractor to the main sampler and extract all response body to some variable. Then add a dummy sampler and put that variable as the response body. Now you will have the information passed to your extractors within the scope.