"OR" operator not working in beanshell assertion - jmeter

During my test, the http response code in the sampler may be 201 or 304. For assertion I ma using beanshell assertion with the following code and it is not working, what I am missing here.
import org.apache.jmeter.assertions.AssertionResult;
String failureMessage = "";
String ResCode = SampleResult.getResponseCode();
try {
if (!ResCode.equals("304") || !ResCode.equals("201")) {
failureMessage = "Got Response Code" + ResCode;
AssertionResult result = new AssertionResult("Expected Response 304");
result.setFailure(true);
result.setFailureMessage(failureMessage);
prev.addAssertionResult(result);
prev.setSuccessful(false);
SampleResult.setStartNextThreadLoop(true);
}
else {
}
}
catch (Throwable ex) {
log.error("Something went wrong", ex);
}

There is no number for which it is true that the number equals 304 and equals 201 at the same time.
Therefore, at least one of the operands of || is always true for any possible value of ResCode. If ResCode is 304, the right-hand operand is true. If ResCode is 201, the left-hand operand is true. For any other number, both operands are true.
(!ResCode.equals("304") || !ResCode.equals("201"))
Therefore the result of || is always true.
You want
(!ResCode.equals("304") && !ResCode.equals("201"))
or equivalently
(!(ResCode.equals("304") || ResCode.equals("201")))

You're using the wrong operator, you need to amend your condition as:
if (!ResCode.equals("201") && !ResCode.equals("304")) {
In general there is no need of any scripting, you can achieve the same using normal Response Assertion:
However if you need to implement more complex custom logic afterwards be aware that since JMeter 3.1 you're supposed to be using JSR223 Test Elements and Groovy language for performance reasons so consider migrating to JSR223 Assertion and Groovy

Related

Getting issue while comparing one property to another in JMeter

In my JMeter test plan, I want to set a flag in case of failure in every HTTP request. So I created a JSR223 PostProcessor in request with the following snippet:
if (!prev.isSuccessful()) {
int abc = 1
props.put('result', vars.get('abc'))
}
where result is defined as global in the thread.
In teardown I want to exit JMeter by comparing with the value of the flag . So I am doing the following:
if ((props.get('result') as int) == 1) {
System.exit(1);
}
Can anyone help me what wrong I am doing in this? Is there any other way by which I can do this.
This statement vars.get('abc') will return null because you just declare an integer called abc and not writing it to JMeter Variables.
You need to amend your code to something like:
if (!prev.isSuccessful()) {
int abc = 1
props.put('result', abc)
}
also there is no need to cast it to the integer back, it's stored as the object of the given type
if (props.get('result') == 1) {
System.exit(1);
}
More information:
Properties aka props
JMeterVariables aka vars
Top 8 JMeter Java Classes You Should Be Using with Groovy
You may also find AutoStop Listener useful

Stop http request after certain condition using JMeter

I have my HTTP request and have some conditions need to wait get at least 1 results or complete=true from the response.
I also want to add if keep executing to satisfy the below condition I want to stop after some request, my code:
if (vars.get('complete') == true || vars.get('total_result') > 0) {
vars.put('stop', true);
}
My request:
I think you are getting a String when getting vars value and failed to compare to 0.
You can parse value as Integer:
int total_result = vars.get('total_result') == null ? 0 : Integer.parseInt(vars.get('total_result'))
if (vars.get('complete') == true || total_result > 0) {
vars.put('stop', true);
}
You have a significant number of errors in the jmeter.log file:
so first of all you need to analyze what's going on there, it might be the case the variables are not having respective values.
Also since JMeter 3.1 you're supposed to be using Groovy language for scripting so consider migrating from JavaScript, moreover it is not available in later Java versions
Also JMeter Variables are stored as Java Strings so you need to perform the strings comparison or conversion of values to the required types
Suggested clause change (again assumes Groovy language):
vars.get('complete') == 'true' || (vars.get('total_result') as int) > 0

How to skip Beanshell PostProcessor ( based on the regular expression output from previous http request ) by adding if controller

I am using JMeter 3.2 and I have a beanshell Postprocessor where it adds a number to the out from the regular expression (from previous HTTP request) ${FollowupBDays}. Here is a snippet of the post-processor:
int FollowupBDays1 = Integer.parseInt(vars.get("FollowupBDays"))+4;
basically the regular expression ${FollowupBDays} returns an integer value Ex: 3, and in the BeanShell post-processor I am adding a number to the regular expression output i.e., 3+4 using the above line from the post-processor. I would like to skip the BeanShell Post-Processor if the regular expression returns null value i.e., if the output from regular expression returns the value since post-processor returns an error while trying to add + 4
Could you let me know the condition I can add to the If controller to skip the BeanSshell Post-Processor when the regular expression ${FollowupBDays} returns the output
I tried the following conditions by adding if controller to the BeanShell post-processor and the condition always skips the post-processor regardless the value returned by the regular expression i.e., when the value is 3 or :
'${FollowupBDays}' != ' '
${__javaScript(vars.get("FollowupBDays") != ' ')}
It's impossible to set any controller, including If Controller, for post-processor.
However you should handle a situation when variable is not an integer in the code of your post-processor itself. Best way is to catch exception:
int FollowupBDays1 = -1;
try {
FollowupBDays1 = Integer.parseInt(vars.get("FollowupBDays"))+4;
} catch(NumberFormatException e) { /* remains -1 */ }
Alternatively, you can check for condition you were trying to use in If controller, before assigning the variable:
String FollowupBDaysAsString = vars.get("FollowupBDays");
if(!" ".equals(FollowupBDaysAsString))
{
int FollowupBDays1 = Integer.parseInt(FollowupBDaysAsString)+4;
}

JMeter BeanShell Assertion: Getting error when convert String to Long

Have a need to change the value from String to Long in BeanShell Assertion to do verification.
First Apporach
long balance_after_credit = Long.parseLong(String.valueOf("${balance_after_credit_from_db}"));
Second Approach
long balance_after_credit = Long.parseLong(vars.get("balance_after_credit_from_db"));
For instance, consider am getting a value as '743432545' for the variable balance_after_credit_from_db.
Error
org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval Sourced file: inline evaluation of: ``long token_balance_after_credit = Long.parseLong(vars.get("token_balance_after_c . . . '' : Typed variable declaration : Method Invocation Long.parseLong
Weird thing is sometimes, I didn't get errors and the script is getting passed.
Can anyone please point out where am doing a mistake. TIA.
Inlining JMeter variables into code-based scripts is not something recommended so go for 2nd approach.
How do you know that exactly String is being returned from the database all the time? It easily can be any other object type, in fact any of described in the Mapping SQL and Java Types article. The way more safe approach will be something like:
if (vars.getObject("balance_after_credit_from_db") instanceof String) {
long balance_after_credit = Long.parseLong(vars.get("balance_after_credit_from_db"));
}
else {
log.error("Unexpected \balance_after_credit_from_db\" variable type");
log.error("Expected: String, Actual: " + vars.getObject("balance_after_credit_from_db").getClass().getName());
throw new Exception("Unexpected variable type");
}
So in case of non-String JDBC query result you will be able to see the relevant message in jmeter.log file
See Debugging JDBC Sampler Results in JMeter article for more information on working with the entities coming from databases in JMeter tests
The second option
long balance_after_credit = Long.parseLong(vars.get("balance_after_credit_from_db"));
should work, provided you have a valid numeric variable value. For instance try to run something like this:
vars.put("x", "743432545");
long balance_after_credit = Long.parseLong(vars.get("x"));
It won't return any exception.
The problem is when the variable is not defined, has empty or non-numeric value. Then Long.parseLong will throw a NumberFormatException, which you shold catch and make use of (treat it as assertion failure):
String rawValue = vars.get("balance_after_credit_from_db");
long balance_after_credit = Long.MAX_VALUE; // initialize with some unrealistic value
try {
balance_after_credit = Long.parseLong(rawValue);
}
catch(NumberFormatException e) {
Failure = true;
FailureMessage = "Variable does not contain a valid long. It was " + rawValue + " instead";
}

display all assertions in View Result Tree

Actually i am creating a test plan using jmeter.In that test plan i have put
many assertions like response assertion,xpath assertion and html assertion.
Now i want to show all assertion result in a single view result tree along with other results...for that i am using the custom code..but its not working.its showing only one assertion result that is last assertion result.so please tell how can i show all assertion in same result tree.My code is
import org.apache.jmeter.assertions.AssertionResult;
AssertionResult[] results = sampleResult.getAssertionResults() ;
for(int i =0,j=1 ; i<results.length;i++) {
AssertionResult result = results[i];
if(result.isFailure() || result.isError()) {
vars.put("assertionResult_" +j, result.getFailureMessage());
j++;
}
}
There is an Out Of The Box component to do this called Assertion Results
Find a tutorial on assertions showing it at:
http://www.guru99.com/assertions-in-jmeter.html

Resources