Use Beanshell Assertion inside a Critical Section Controller - jmeter

I'm trying to use Beanshell Assertion inside a Critical Section Controller, but it seems to be ignored. Does someone know why is this behaviour? have I missed something?

JMeter Assertions are executed only in context of the Sampler, if there is no sampler which generates a SampleResult in the Assertion's scope - it will not be executed.
Also be aware that since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language for scripting so consider migrating to JSR223 Assertion on next available opportunity

assertions apply to all samplers which are in their scope
Assertion, for instance, is hierarchical in the test tree. If its parent is a request, then it is applied to that request. If its parent is a Controller, then it affects all requests that are descendants of that Controller.

Related

Jmeter extract data from Sampler Result

I need extract some string from Sampler Result, for example Latency:. How can i do that? Using regex function?
I don't think you will be able to extract the Latency using Regular Expression Extractor, if you need this metric as a JMeter Variable I would rather suggest going for JSR223 PostProcessor and the following code:
def latency = prev.getLatency()
vars.put('status', latency as String)
where:
prev is a shorthand for SampleResult class instance
vars is a shorthand for JMeterVariables class instance
See Javadoc for the aforementioned classes to see the available properties and functions and Top 8 JMeter Java Classes You Should Be Using with Groovy article to learn more about JMeter API shortcuts available for the JSR223 Test Elements
Demo:
the value can be referred as ${status} where required

why we will use prev.getResponseCode() in jmeter

If give String ResponseCode = prev.getResponseCode(); in beanshell assertion it's working good.
But if use String ResponseCode = getResponseCode(); I am getting error, so what is the reason for this?
JMeter is a Java application , which is an Object Oriented language.
In the element you use, JMeter exposes few scripting objects described here:
http://jmeter.apache.org/usermanual/component_reference.html#BeanShell_Assertion
One of them is SampleResult exposed under name « prev ».
This object is an instance of class :
http://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html
By the way you should move to JSR223 Assertion using groovy.
prev is a shorthand for previuos SampleResult, see the JavaDoc for all available methods and fields.
Depending on parent sampler type it might resolve into different classes, i.e. HTTPSamplerResult which may provide more useful methods.
Also if you look at the bottom of the Beanshell Assertion test element you will see some other pre-defined variables which you may find useful:
As you can see there is already a ResponseCode variable which holds current sampler response code.
Check out How to Use JMeter Assertions in Three Easy Steps article for comprehensive information on different assertion types.

How to pass a non-string value between two JSR223 (groovy) samplers in JMeter?

In JMeter I need to pass a value from one JSR223 sampler (groovy) to another one within the same Thread group. For now I use a User Parameter (vars.put(...), vars.get(...)) but it has a disadvantage that extra conversions to and from string are required to pass non-string data. Is there a way to pass an object (e.g. Integer or Date) between two groovy samplers in JMeter?
As per How to use BeanShell: JMeter's favorite built-in component guide:
vars
vars is the most frequently used component which represents JMeter Variables. It’s an instance of org.apache.jmeter.threads.JMeterVariables class and provides read/write access to current variables, capable of enumerating/changing existing, creating new ones and obtaining nested properties.
If you look into JMeterVariables class JavaDoc by following above link you'll be able to see putObject(String key, Object value) method which seems to be what you're looking for.
So in the first sampler:
Date now = new Date();
vars.putObject("now", now):
And in the second sampler:
Date then = vars.getObject("now");
Alternatively you can use props.put(String, Object) and props.get(String, Object) - in that case you will be able to access the values from different Thread Groups.

JMeter assertion modularity (can I re-use assertions?)

I am working on a test plan for our REST web application and we have several common test types which have common criteria we want to test for. For example, when creating entities through the API we have a common set of expectations for the JSON response; id should be set, created date should be set, etc.
Now, I would like to model my plans like this:
Thread Group
Users (Simple Controller)
User Create Tests (Simple Controller)
Create Test 1 (Sampler)
Create Test 2 (Sampler)
Create Test 3 (Sampler)
Common Creation Asserts (Module Controller)
User Delete Tests (Simple Controller)
Samplers...
Common Delete Asserts (Module Controller)
Events (Simple Controller)
Event Create Tests (Simple Controller)
Samplers...
Common Creation Asserts (Module Controller)
Event Delete Tests (Simple Controller)
Samplers...
Common Delete Asserts (Module Controller)
Thread Group for common assertions (disabled)
Common Creation Assertions (Simple Controller)
BSF Assertion 1
BSF Assertion 2
BSF Assertion 3
Common Delete Assertions (Simple Controller)
Asserts...
Now, I understand how the scoping works and that if I placed assertions where the BOLDed module controllers are they would be invoked for each sampler. However, I'd rather not have to copy-paste-maintain numerous copies of the same assertions in each of these locations. Hence, why I want a way to define assertions once, and invoke where appropriate.
However, with this approach, the ACCENTed assertions placed in the common simple controllers are never invoked (confirmed by using a BSF assertion with logging messages). If I place an additional sampler in the common assertions simple controller it is invoked. But only a single time.
I'm using JMeter 2.12 but have confirmed that JMeter 2.8 behaves the same way.
So, how can I use JMeter to define assertions once, and re-use them anywhere?
Thanks!
There is no way to do this.
You can try factoring by using Variables within Assertions, thus if it's a Response Assertion you will factor out this.
I ended up getting creative.
Using JSR223 assertions in Javascript I've accomplished what I wanted. This is a natural fit because all the response data I want to test is in JSON, YMMV.
In User Defined Variables I define the tests I want to perform using Javascript.
Tests like:
TEST_JSON:
try
{
eval('var obj = ' + prev.getResponseDataAsString());
} catch(e)
{
setFailed();
}
TEST_RESULT_SUCCESS
if(obj.status != "success")
{
setFailed();
}`
Then in the assertion(s) I can do something like:
eval(vars.get("TEST_JSON"));
eval(vars.get("TEST_RESULT_SUCCESS"));
And I don't have to re-write tests over and over and over.
I even have some a some utility functions that I can add to my assertion by doing
eval(vars.get("TEST_UTIL"));
which allows me to print additional logging from my assertions if I desire.

Reuse Extractors?

I've used a Module Controller to invoke a Test Fragment. This is a great way to reuse Controllers and Samplers across multiple Thread Groups.
I have a set of about a dozen Extractors (CSS and RegEx) that I'd like to reuse for different HTTP Samplers. (The Samplers would be different, but the Extractors I'd run against each would be the same.)
Is there a way I can accomplish this?
You have 2 options:
You can use scopes if it applies , see http://jmeter.apache.org/usermanual/test_plan.html#scoping_rules
Otherwise put you CSS expressions in Variables and use them in extractor

Resources