When there is the need to create load tests or performance tests for an application, Apache JMeter is a handy tool and set up with ease.
In the following short tutorial I’d like to demonstrate how to configure JMeter to log into a Java EE web application with multiple users specified in a CSV file, how to generate some basic reports and how to integrate JMeter into a mavenized build using the JMeter Maven Plugin.
JMeter Download and Maven Dependencies
Apache JMeter may be obtained at the JMeter Download Site.
To enable our Maven build to run JMeter test plans, we only need to add the following dependency for the JMeter Maven Plugin to our pom.xml:
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>1.10.0</version>
<executions>
<execution>
<id>jmeter-tests</id>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
</executions>
</plugin>
Multiuser Java EE Web Application
We need some kind of web application with multi-user support. For this purpose we’re using the application from my tutorial: “Java EE: Setting up and Testing Form-Based JDBC Authentication with Arquillian and Maven” and we’re adding additional four users to the application:
Here is an excerpt from the initialization bean, for the full application sources, please feel free to skip to "Tutorial Sources":
@Singleton
@Startup
public class ApplicationConfigurationBean {
// creates 5 users: admin, ted, lisa, marge, bart
private final String[] createUserStatements = {
"INSERT INTO `users` VALUES('admin', 'test')",
"INSERT INTO users_groups VALUES('administrators','admin')",
"INSERT INTO `users` VALUES('ted', 'foo123')",
"INSERT INTO users_groups VALUES('administrators','ted')",
"INSERT INTO `users` VALUES('lisa', 'xyz123')",
"INSERT INTO users_groups VALUES('administrators','lisa')",
"INSERT INTO `users` VALUES('marge', 'redrum')",
"INSERT INTO users_groups VALUES('administrators','marge')",
"INSERT INTO `users` VALUES('bart', 'eatmyshorts')",
"INSERT INTO users_groups VALUES('administrators','bart')"
};
@Resource(lookup = "jdbc/hascode_test_db")
private DataSource ds;
@PostConstruct
protected void onStartup() throws SQLException {
[..]
for (String sql : createUserStatements) {
con.prepareCall(sql).execute();
}
[..]
}
}
Creating the Test Plan in JMeter
Now we’re ready to create a new test plan by starting JMeter and adding a new test plan.
Creating a new Thread Group
A thread group controls the number of threads JMeter will use to execute our test.
Each thread group represents a single user and therefor needs an isolated cookie manager to store the state of our HTTP connection.
We’re adding a new thread group with Numbers of Threads set to 20.
Adding a Cookie Manager
To this thread group, we’re adding a new cookie manager so that the authentication cookie from our web application is working but isolated in each thread.
Adding a CSV Datasource
As we have multiple users logging into our web application, we’re adding a CSV file containing username and password in the format <username>,<password>
This is our users.csv
admin,test
ted,foo123
lisa,xyz123
marge,redrum
bart,eatmyshorts
Each thread of the thread-group gets an entry from this datasource assigned, so it is important not to add the datasource as a child of the thread group but as a child of the test plan.
The configuration for this data source should look like this one:
Recording User Activity with the HTTP Test Script Recorder
The most comfortable way to record the test user’s interaction with our web application is to record everything using the HTTP Test Script Recorder and is done like this:
-
Add a HTTP Test Script Recorder to the Workbench
-
Configure the Recorder’s HTTP-Proxy
-
Configure your browser to use the Recorder’s Proxy
-
Start recording
-
Browse through the application
-
Fine-tune the recorded steps
The following screenshot shows the configuration of our HTTP Test Script Recorder.
It’s important to set out thread group as target controller so that the steps recorded are assigned to this unit.
Following redirects is necessary because the security layer in our web application redirects to the login form when not authenticated.
Setting up the Proxy
We’re setting the recorder’s HTTP proxy to run on port 9000 – the port should not interfere with the web application’s port.
Browser Configuration
Now we need to set this HTTP proxy in our browser.
Because switching between proxy servers is a common task for me, I’m using a Firefox addon, FoxyProxy here to switch between different proxy servers with one click or domain based.
The following screenshots displays a sample FoxyProxy configuration, otherwise simply add localhost and port 9000 to the regular proxy settings our your browser:
Recording
To start recording, we simply need to press “Start” in the Recorder screen in JMeter and then continue in our browser by accessing our web application.
For this demonstration we want to ..
-
Access the application’s start page
-
Log into the application
-
Access the URL where the current user’s information is displayed in the JSON format
After the run we should see several steps added to the thread group.
Login Configuration with CSV Data
Out CSV data-source provides us with the username and the password – we now simply need to add the placeholders for this local variable as parameters for the HTTP request where the authentication takes place.
The placeholders are ${username} and ${password} as specified by the CSV data-source configuration.
Adding Reports
Finally we may add some reports (Test Plan > Listeners > ..) customized to our needs:
Aggregate Graph
This is an example for an aggregate graph added to our test plan:
Aggregate Report
This is an example for a simple aggregate report added to our test plan
Adding Assertions
Finally we should add some assertions to the JMeter test..
Verifying the JSON Response
We’re verifying the response of the session REST service by adding a Response Assertion. For more complex JSON verification, there is a specialized JSON plugin for JMeter that might be helpful.
Duration Assertion
By adding this assertion to the thread group, we’re testing verifying the duration of a walk through the application for a single user (I used 2 seconds here, instead of 20ms!) :
Directory Structure
The following files have been added to our normal web project to enable JMeter with maven and add the test plan and the CSV file containing the user information:
.
├── pom.xml
└── src
└── test
└── jmeter
├── multiuser-profiling.jmx
└── users.csv
Running JMeter with Maven
Running the test plan in the JMeter GUI is a nice thing but for a close integration into our mavenized build lifecycle, the JMeter Maven Plugin allows an execution with Maven like this:
mvn jmeter:jmeter
[INFO] ------------------------------------------------------------------------
[INFO] Building hascode 1.0.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- jmeter-maven-plugin:1.10.0:jmeter (default-cli) @ jmeter-multiuser-profiling ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] P E R F O R M A N C E T E S T S
[INFO] -------------------------------------------------------
[INFO]
[INFO]
[info]
[debug] JMeter is called with the following command line arguments: -n -t /data/project/jmeter-multiuser-profiling/src/test/jmeter/multiuser-profiling.jmx -l /data/project/jmeter-multiuser-profiling/target/jmeter/results/20150118-multiuser-profiling.jtl -d /data/project/jmeter-multiuser-profiling/target/jmeter -j /data/project/jmeter-multiuser-profiling/target/jmeter/logs/multiuser-profiling.jmx.log
[info] Executing test: multiuser-profiling.jmx
[info] Completed Test: multiuser-profiling.jmx
[INFO]
[INFO] Test Results:
[INFO]
[INFO] Tests Run: 1, Failures: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.814s
[INFO] Finished at: Sun Jan 18 16:44:35 CET 2015
[INFO] Final Memory: 11M/205M
[INFO] ------------------------------------------------------------------------
Tutorial Sources
Please feel free to download the tutorial sources from my GitHub repository, fork it there or clone it using Git:
git clone https://github.com/hascode/jmeter-multiuser-profiling.git
Alternative: Gatling
I have written a tutorial about another tool for writing load tests – please feel free to have a look: "Load Testing Web Applications with Gatling and Maven".
Article Updates
-
2016-05-06: Link to Gatling tutorial added.
-
2015-03-03: Added example assertion to verify the JSON response and a to verify the duration of the login process (thx @Wade Xu for the remark) .