The key to all good automation is modularisation which is effectively isolating small chunks of your application under test into separate tests and then re-using these smaller chunks in your larger, more complicated tests.
Example of good candidates for modularisation are logon and logoff as well as any other high-volume journeys through your application such as search functionality.
The rationale for this approach is that if these high volume common functional activities change you only need to make the update in a single test rather than in multiple tests.
If your business functionality is only used once in a single script rather than many scripts it makes no sense to modularise it but if it is used twice, or more, then it should be considered.
Sample JMX files for this tutorial are available for download:
Test Fragments, Module Controllers and Include Controllers
The way that JMeter approaches the subject of modularisation is in the form of Test Fragments combined with Module Controllers or using Include Controllers and both approaches are extremely useful when you have complicated tests that support many concurrent user journeys.
The approach to modularisation changes depending on whether you are using a combination of Test Fragments and Module Controllers or using a Include Controller and both approaches will be discussed.
You need some discipline in your scripting standards if you are going to use a modularised approach as you need to ensure that each module can carry on where the previous one left off with no missing steps.
An example being that if you modularise your logon and the logon finishes with the application in a certain place and state then all scripts that execute directly after your logon must start from the place the modularised logon component left the application under test.
Test Fragments and Module Controllers
Let’s start with the basics, creating and calling a Test Fragment.
Under the JMeter Test Plan element add a Test Fragment
Add test fragment
Now under our Test Fragment lets add a Dummy Sampler to simulate a logon, a logon script will generally be much more complex, but this is a simple way to demonstrate the process.
Logon dummy sampler
We have now created our first fragment, named
Let’s look at how we use this.
We create a Thread Group and add a Module Controller to the Test Plan:
Add module controller
Under the Module Controller you can see a list of Modules:
Module controller overview
If we select the
logon fragment we created earlier what we are doing is selecting our Test Fragment to run in the place of the Module Controller.
We will add a Results Tree Listener to our test and run it:
Simple module controller results
We have successfully run our Test Fragment, but you may be wondering what the point of this is as we could have just run the
logon Dummy Sampler under the Thread Group and achieved the same results.
To demonstrate the real power of Test Fragments we need to create a few more, lets add a Test Fragment that simulates a
logoff and one that simulates an application
Multiple test fragments
We can now use these in a more complicated test, if we had a set of 3 tests that:
Test 1 (add-new)
- Logged on
- Added a new item
- Logged off
Test 2 (update-existing)
- Logged on
- Search for item
- Update existing item
- Logged off
Test 3 (delete-existing)
- Logged on
- Search for item
- Deleted item
- Logged off
Then we only need to write 3 new tests to support the add new item, update item and delete item.
The rest of the user journey can be supported by our Test Fragments.
For the purposes of our example we will use Dummy Samplers for the new tests giving us a Test Plan like this.
Multiple fragment example
If we add a View Results Tree listener and execute our tests we can see the execution of the fragments and samplers.
Complex sampler execution
If, for example, the
Logon changes we only need to change in one place (our Fragment) and the tests will all still run.
This is the benefit of modularisation, if you consider a much more complicate test suite with a lot of tests and a change was made to an aspect of the application under test with a modularised approach the scripting rework is kept to a minimum.
Test Fragments and Include Controllers
The other way that JMeter can be used to modularise your tests is by using the Include Controller, we will start with a basic example.
Include Controllers as their name suggests allows you to include other .jmx files into you tests and therefore the same benefits we saw with using our Module Controller are true here as well.
An Include Controller will only execute the part of a referenced test that exist under a Test Fragment.
Before we move on to the Include Controller let’s look as what the included .jmx file needs to look like to be used in a modular way.
Example .jmx to include
The example above contains a Thread Group with Dummy Samplers and two Test Fragments that contain several Dummy Samplers.
This is not a good example of a script built for modularisation and the best way to explain why this is the case is to demonstrate its use as an included test which we will do shortly.
Let’s look at how an Include Controller works.
Simple include controller
Our simple Include Controller makes a reference to our example .jmx file we discussed earlier.
If we execute this test these are the results that we get.
Simple include controller results
You can see that only the first Test Fragment was executed and not the Thread Group or the second Test Fragment.
Therefore, the example .jmx file we discussed earlier is not a good example because the object of modularisation is to have small chunks of functionality that you bolt together to perform a test on your application.
Let’s look at a better way for Include Controllers to be used.
Single fragment example
This is an example of a .jmx file that we could use in a modularised way, it is simple and covers a relatively small part of an application user journey that might be repetitive.
We can now look at ways of using this .jmx file in modular way.
Complex include controller
What we have here is Test that includes the .jmx file above and then performs an:
And these will be run after the steps:
As these are the samplers in the included .jmx file.
If we now run this test, we get these results.
We can see again in this example that should any of the samplers in the included .jmx file change then we only need to change a single test rather than multiple.
Reality and Benefits
At the outset of your performance testing journey when you only have a handful of tests the effort to modularise them can seem like an overhead you don’t really want but as your tests start to grow and as the application you are testing evolves and changes you will see the benefits.
The biggest issue around automation has always been the time taken for script maintenance and as your test numbers start to grow modularisation will be a huge benefit.
Modularisation also helps in the distribution of the maintenance effort across a team, large complex scripts are difficult to debug and understand for someone who is unfamiliar with them, but a small single function test is straightforward to understand and to maintain meaning the maintenance effort can be distributed.
This are simple examples and are here to demonstrate the point of modularisation and the benefits it brings.
It does require a bit more planning that just developing scripts that cover a single user journey but this additional effort is worth it and will see any maintenance effort once the scripts are build reduce.
Thank you for this very usefull post. Could you tell us what is your recommendation for handling shared variables between test fragments?