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.
Related
[main-sub projects][1][1]: https://i.stack.imgur.com/1YL97.jpg
As shown in the picture, I've created two JMeter projects (Main. JMX, Sub1.JMX). The main.JMX has a thread group (Subscription) that has include controller to run the Sub1.jmx project.
Sub1.JMX is created with a Thread Group (Subscription) and Test Fragment. All the reusable functionalities are added under the test fragment such as Sub1-Login, Sub1-Logout, and Sub1-close using the simple controllers. A test case (Test Case-1) is created under the thread group Subscription that is invoking Sub1-Login, Sub1-Logout simple controllers using module controller. The Sub1-close simple controller is not used in the test case.
When I run the Main.JMX, is executing the test case (Test Case-1), which includes login and logout and also remaining simple controllers from the test fragment (Sub1-close).
what is the best way to run only simple controllers (defined in the test fragment) referenced in the test cases?
JMeter's Module Controller runs a Test Fragment. Entire.
If you don't want to run a certain part of the test fragment you have 2 options:
Either put it under the If Controller and come up with a JMeter Function or Variable which will control whether it will be executed now or not
Or split your Test Fragment into 2 (or more) separate fragments and compose your "test case" from smaller parts .
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.
I am using Jmeter and I saw simple controller and module controller and I could not understand the difference between them.
I tried adding them both but I don't know how to use them more efficiently.
Can anyone please help me?
Module Controller can be used to run other Logic Controllers, for example if you have a Transaction Controller which implements Login and you are creating a test assuming different groups of users which need to be logged in - you can call the aforementioned "Transaction Controller" using the Module Controller in 2 different Thread Groups instead of copying and pasting it.
See Using JMeter Module Controller article for more information.
Simple Controller actually does nothing apart from grouping Samplers. You might use Simple Controller in the Module Controller or apply a single Post-Processor, Assertion, Pre-Processor, etc. to all Simple Controller's children. Apart from these two use cases it doesn't add any value.
Simple Controller is just a container to group samplers in it and apply some scoping rules for example:
http://jmeter.apache.org/usermanual/component_reference.html#Simple_Controller
Module Controller is a way to reuse code accross your test:
http://jmeter.apache.org/usermanual/component_reference.html#Module_Controller
Module controller can be used to choose between Simple Controllers see example
Module controller will allow me to run only selected simple controller's requests.
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
Is there a way in MBUnit to have the same test called multiple times with different parameters in a sequence, as such:
Method1()
Method2(param A)
Method3()
Method2(ParamB)
Method4()
Method2(ParamC)
etc? I've tried using the Order parameter but sadly I was too hopeful in that the Ordering would be considered class-wide rather than test-wide (1,2,3,4,5,6 as opposed to 1,2a,2b,2c,3,4).
Can you explain the reasons for needing this? This sounds like you have dependencies between your test methods, which in general isn't a good way to go about writing test code.
If you need something to be called in a particular sequence then why not simply expose it as a single test method which calls certain submethods in the order of your choosing?