Overview:
As part of performance testing, I had to come up with performance test scripts for various use cases / business workflows for our application. When I design my performance test scripts, I will ensure that I have reusable test scripts as mentioned in this article.
JMeter – How To Create Reusable & Modular Test Scripts
If you have not read this article already, I would request you to read the article first and proceed with this article! As part of the above article, you can learn how to properly design your performance test scripts / test plan.
In a high level, I maintain a reusable ‘test script’ modules under ‘Test Fragment’. Then I use Module Controller to call specific modules to create the workflow.
I also create multiple ‘Thread Groups’ for each business functionality / workflow.
Once you have a test plan as mentioned above with multiple thread groups, then let’s see how we could maintain the JMeter test plan using Property files & running a specific thread group on a specific environment in this article!
Creating a Simple Test Plan:
Let’s consider an application with below business functionalities.
- New User Registration
- User Login & Order Creation
- User Login & Product View
- Existing Order Edit/Cancel
- User Search
Lets also assume that we already came up with performance test plan with multiple thread groups as shown above. Each thread group will perform the specific functionality.
Sample Performance Test Requirement:
Now Lets assume we have performance requirements like,
- Test each module independently (just run 1 thread group at a time).
- Test combination of modules (more than 1 thread group / all).
- Test in different environment (same test in different environment – In my project, I also run the same test in 2 different environments – QA & Staging).
Parameterizing Environment Details:
- First, lets create different property files containing the test-environment details for each environment.
# QA.properties
test.environment.hostname=10.11.12.14
test.environment.port=8080
test.environment.protocol=http
# Staging.properties
test.environment.hostname=10.11.12.13
test.environment.port=443
test.environment.protocol=https
- Now add a ‘Property File Reader‘ to read specific environment details at run time.
- Then remove all the Server Name/IP, Port, Protocol details from the HTTP Requests/Samplers in your test plan.
- Let the HTTP samplers have only the Path, Parameters, other request specific information.
- Add a HTTP Request Defaults under Test plan as given below.
(If the HTTP request is missing an information, JMeter will get that from HTTP Request Defaults. So, updating IP, port details in one place will get reflected for the entire test).
Note:
- ${__P(test.environment.hostname)} will retrieve the value of the ip address or hostname given in the property file.
Now your test plan is modified to run the script on any given test environment.
Parameterizing Thread Group Details:
- We have multiple thread groups in our test plan.
- We will be passing thread group user count, ramp-up period, thread group duration information via property files to the test. Lets create a property file as given below.
# Anonymous User - Product Search
group1.usercount=10
group1.rampup=10
group1.duration=600
# New User Registration
group2.usercount=10
group2.rampup=10
group2.duration=600
# User Login & Order Creation
group3.usercount=10
group3.rampup=10
group3.duration=600
# User Login & Existing Product View
group4.usercount=10
group4.rampup=10
group4.duration=600
# BackOffice Admin User Activities - Existing Order Edit/Cancel
group5.usercount=10
group5.rampup=10
group5.duration=600
- All the thread groups should be modified to use the properties as given below.
- To run 1 specific thread group, we can change the user count (number of users) property for the Thread Group. for ex, If we need to run only ‘New User Registration’ module, user count property can be set to 0 for all other modules.
Note:
If the Thread Group user count is 0, JMeter can not execute the Thread Group. By updating thread group user count property to 0, a thread group can be disabled.
- Lets create a multiple property files with different combinations as you might be interested. For ex, anonymoususers-only.properties will have below properties.
# Anonymous User - Product Search - Only
# Anonymous User - Product Search
group1.usercount=100
group1.rampup=100
group1.duration=3600
# New User Registration
group2.usercount=0
group2.rampup=0
group2.duration=0
# User Login & Order Creation
group3.usercount=0
group3.rampup=0
group3.duration=0
# User Login & Existing Product View
group4.usercount=0
group4.rampup=0
group4.duration=0
# BackOffice Admin User Activities - Existing Order Edit/Cancel
group5.usercount=0
group5.rampup=0
group5.duration=0
So, I create multiple property files to control specific thread group execution.
- registration-only.properties
- ordercreation-only.properties
- all-modules.properties..etc
Add one more ‘Property File Reader’ to read specific module you are interested in executing.
Controlling Thread Group & Environment via Command Line:
- At this point, We have created a JMeter test plan as explained above with 2 Property File Readers.
- Now, lets parameterize the environment and module using properties which I will pass via command line at run time.
Rest is simple!!!
- To run all modules on Staging environment
jmeter -n -t test.jmx -l result.jtl -Jenvionment=staging -Jmodule=all-module
- To run all modules on QA environment,
jmeter -n -t test.jmx -l result.jtl -Jenvionment=QA -Jmodule=all-module
- To run order creation module on Staging,
jmeter -n -t test.jmx -l result.jtl -Jenvionment=staging -Jmodule=ordercreation-only
To run registration module on QA,
jmeter -n -t test.jmx -l result.jtl -Jenvionment=QA -Jmodule=registration-only
Triggering Thread Groups via Jenkins:
If we use Jenkins to run our test, these test environment & module can be drop down list containing the possible values & passed as parameters from Jenkins to JMeter.
Thus, We can run specific thread group on specific environment without modifying the JMeter test as given below.
More details on JMeter-Jenkins integration can be found here.
Summary:
By properly designing the JMeter test plan with reusable test scripts, multiple thread groups and Property File Reader etc, we are able to control specific thread group execution at run time.
So we can focus on performance related issues for a specific module instead of running the whole test plan every time.
Happy Testing & Subscribe 🙂
Under “To Read properties” para: I do not understand how you have written ${__P(host)} function. Do we need to configure the list of hosts like PPE1 and PPE2 in a separate properties file and call them here in the script.
I pass the ‘host’ property via command line. -Jhost=ppe1 -> ${__P(host)} will return ppe1
Buddy, I have done the setup whatever mentioned in the above blog, while running in the command line
I use Linux system.
[jmeter@lab projects]$ jmeter -n -t tests.jmx -l testresults.jtl -R 10.1.1.100 -JHost=qa
This is how I am passing command line. But when I hit enter
it is showing JMeter command not found. Please help..
Do you have java installed?
Follow the steps mentioned in this site.
http://www.hotwaxsystems.com/quality-assurance/setup-apache-jmeter-in-linux-environment/
In linux, you might have to run below command
./jmeter -n -t tests.jmx -l testresults.jtl -R 10.1.1.100 -JHost=qa
Yes I do have the java installed on Linux machine.
Thanks for command line sample and
I tried with my project command line. It isnt working. It says” Could not open test.jmx file..
It is a different error. So JMeter seems to be working.
For this, you can provide the absolute path to the jmx.
ex:
./jmeter -n -t /path/to/test.jmx
Fixed.. It is working fine.. Thanks for the detailed explanation in this blog..
Just have a small query: How does the all-modules.properties file look like: Please provide me an example
The property file is same. Only the values will be present. If you need to run the all the thread groups – you need to have the thread count > 0.
If you need to disable a thread group, thread count should be 0.
I tried running the same test remotely with 3 slave machines (Distributed testing) with the above steps mentioned in this blog. I get the below error:
“Error in rconfigure()method java.rmi.serverexception: RemoteException Occured in server thread; nested exception is:
java.rmi.UnmarshalException:error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException:com.tag.jmeter.ext.config.propertyReader (no security manager: RMI class loader disabled)”
Am I missing something anything in my test. (or) do I need to configure something to override this?
Please advice..
Please ensure that you place the Property File Reader jar in all the slave machines.
Well, I think your blog is pretty good and have lots of useful information about What is the thread group in Jmeter . Keep it up!
Could you please share your jmx and .properties file?
I am new on jmeter and some of the step i don’t really understand.
Would like to learn it from your jmx file
many thx
I did this long back. So I do not have it now. But, using the given screenshot, you can create a simple script.
and what is the value for loop = “forever” in properties file?
-1 is forever.
from screenshoot, properties path is hardcoded to c:\xxx
can we use relative path?
my_dir
|——-my_properties
my_dir contains my .jmx file and my_properties contains my .properties file,
what should i add in the properties file reader?
${__P(host)}.properties
Yes, you can use relative path (path from .jmx file)
Great article, Vinoth as always!
basically the issue is that the value -Jhost=hostname is not passed onto your plugin by ${__P(host))}.. do you have an idea why? I am using JMeter 3.1 r1770033
Fasa,
I see that your usage is wrong. ${(__P(host)} – change this to ${__P(host)}
My test data varies depending on environment.
If it is qa, then we hv to use test data1( path of csv file )
If it is system test then we hv to use test data 2(path of csv)
How to handle this scenario
That is what the article explains. You keep any such info in the properties file. for ex: you have 2 different files like qa.csv, prod.csv etc. then you have a property called testdata.filename=qa.csv for qa.properties, testdata.filename=prod.csv for prod.proeprties. by using ${testdata.filename} you use the appropriate file.
Great Article
I spend a lot of time to start using -J on remote machines, but if u work with jmeter slaves u must use -G param, not -J
Hi Vln,
Thanks for this blog post. Nice read
I thought about this approach for my work, where i have a single test plan jmx file, which contains various thread groups… and am planning to use this single test plan for my various types of performance testing, say smoke testing,capacity testing,soak testing etc. .. so for all these testing the user load, rampup, duration etc varies as we know . and also as I have around 5 thread groups which concentrate on 5 application flow/scenarios. and with each scenario I might be interested to do one type of perf testing say capacity testing for different loads. and also combination of these scenarios with thread output controller to mimic real time behavior.
so if i maintain different properties file for each of these combinations of requirement, and can pass the respective one based on the type of test/scenario/userload-rampup requirement choosen by tester.
but the problem i see here is I would need to maintain so many properties file here. though i wont be updating it more often
do you think its a good practice ? is there any better alternate here ?
I tried not to keep the property file , but pass the parameter to jmeter during time time from jenkins… but it was giving me java memory error, due to passing many arguments i believe
using Jmeter + Maven plugin is what i thought of trying now.. where i can pass run parameters as many i want i guess..so parameters chosen by tester from jenkins ui will be passed to maven
please let me know if you have some idea in this situation
Warm Regards, Musaffir