Loadunit is a Junit-based framework for unit-testing of scalability and performance. It enables running completely automated load-tests of software and generates reports about the throughput and performance of tested applications.
You can view a sample HTML report generated by Loadunit.
You can view the Loadunit Sourceforge Project Page for the latest information about Loadunit.
Loadunit is written and maintained by Bryan Che.
Loadunit is a Junit-based framework written in Java for unit testing of scalability of performance. It should run in any environment with Java 1.4 or greater.
People may use Loadunit for testing many types of applications. Loadunit is particularly well-suited for testing Web-based applications and includes several tests specifically for testing Web applications.
Developers can write Junit tests for the Loadunit framework and use these tests for automated scalability tests. Loadunit will ramp up to a configurable number of virtual users, each running these tests. Furthermore, Loadunit supports having each of these users test with different data from each other in order to generate realistic load patterns.
Loadunit allows control over how to ramp up virtual users for testing and features automatic bottleneck-detection to stop load tests once these tests have reached a scalability bottleneck. Loadunit also generates reports containing charts of Throughput-Vs-Users and Performance-Vs-Users data for test runs.
Many different types of load-testing software already exist. Why would you want to use Loadunit, then?
Loadunit will not replace a sophisticated load-testing tool. But, Loadunit can prove to be valuable and complementary to traditional load-testing software in a couple of significant ways:
Loadunit requires Java 1.4 to run. Loadunit also depends upon several free software libraries:
Loadunit includes jar files for all these libraries in its distribution.
The easiest way to setup Loadunit is to install it on the same machine as the application you want to test. Indeed, developers may want to do this so that they can quickly check if changes they make impact scalability or performance. Running Loadunit on the same machine as the tested application, though, is not a good configuration for long-term, repeatable unit-testing. This is because Loadunit itself will greatly affect the machine's performance.
The ideal configuration for Loadunit is to place Loadunit on a separate machine from the tested application's machine. However, Loadunit's computer and the tested application's computer should be on the same high-bandwidth network so as to remove network issues as a potential bottleneck in your application testing.
Loadunit's machine should also be powerful enough to generate the type of load with which you want to test. When running Loadunit for the first few times, monitor Loadunit's CPU and memory usage to make sure that neither one hits 100% utilization. Otherwise, your test results will reflect a bottleneck in Loadunit's own performance rather than your application's performance.
Loadunit can generate over 500 virtual users on a dual-PIII 1.4 GHz box with 1 GB of RAM without any problems.
For more detailed information about configuring Loadunit, see the Loadunit Parameters section.
To download the latest release of Loadunit, go to https://sourceforge.net/project/showfiles.php?group_id=119363.
Loadunit comes in a zip file. This zip file contains Loadunit documentation (including this document), a Loadunit jar file, jar files on which Loadunit depends, and also the Loadunit source code.
To install Loadunit,
LOADUNIT_HOME
.LOADUNIT_HOME/lib
to your
classpath.
For example, On Linux, using bash, do
CLASSPATH=$CLASSPATH:$LOADUNIT_HOME/lib/loadunit-1.0.jar CLASSPATH=$CLASSPATH:$LOADUNIT_HOME/lib/commons-httpclient-2.0.1.jar CLASSPATH=$CLASSPATH:$LOADUNIT_HOME/lib/concurrent.jar CLASSPATH=$CLASSPATH:$LOADUNIT_HOME/lib/jfreechart-0.9.19.jar CLASSPATH=$CLASSPATH:$LOADUNIT_HOME/lib/commons-logging-1.0.2.jar CLASSPATH=$CLASSPATH:$LOADUNIT_HOME/lib/jcommon-0.9.4.jar CLASSPATH=$CLASSPATH:$LOADUNIT_HOME/lib/junit-3.8.1.jar CLASSPATH=$CLASSPATH:$LOADUNIT_HOME/lib/log4j.jar export CLASSPATH
On Windows, do
set CLASSPATH=%CLASSPATH%:%LOADUNIT_HOME%\lib\loadunit-1.0.jar set CLASSPATH=%CLASSPATH%:%LOADUNIT_HOME%\lib\commons-httpclient-2.0.1.jar set CLASSPATH=%CLASSPATH%:%LOADUNIT_HOME%\lib\concurrent.jar set CLASSPATH=%CLASSPATH%:%LOADUNIT_HOME%\lib\jfreechart-0.9.19.jar set CLASSPATH=%CLASSPATH%:%LOADUNIT_HOME%\lib\commons-logging-1.0.2.jar set CLASSPATH=%CLASSPATH%:%LOADUNIT_HOME%\lib\jcommon-0.9.4.jar set CLASSPATH=%CLASSPATH%:%LOADUNIT_HOME%\lib\junit-3.8.1.jar set CLASSPATH=%CLASSPATH%:%LOADUNIT_HOME%\lib\log4j.jar
Loadunit uses three main types of classes for running tests:
LoadunitTestCase
interface extends the basic Junit
Test
interface and adds methods for performing operations
before and after a load test as well as for setting parameters like
throughput and performance requirements. You can think of a
LoadunitTestCase
as what one virtual user will do in a
multi-user load test.
LoadunitTest
is a single load test. It takes a
LoadunitTestCase
and ramps up many virtual users to do
scalability and performance tests with that
LoadunitTestCase
. LoadunitTests
have
configurable settings for things like how to rampup virtual users, the
maximum number of virtual users with which to test, and whether to
automatically stop the test when a bottleneck is detected.
LoadunitTests
also write out charts and data for their
results.
LoadunitSuite
is a suite of LoadunitTests
.
This class allows you to set common settings for a group of
LoadunitTests
and to run them all with these settings. At
the conclusion of its run, a LoadunitSuite
will generate
a report summarizing the results of all the individual tests it ran.
LoadunitSuites
take LoadunitCases
and wrap
them in LoadunitTests
for running.
When you write tests for running in Loadunit, you will create classes
that implement the The
org.loadunit.LoadunitTestCase
interface.
LoadunitTestcase
is the basic type of test in the Loadunit
framework. It provides three main methods for controlling a test:
The LoadunitTestCase
interface also has methods for
setting/getting the name of a test and for setting/getting throughput
and performance requirements.
Loadunit comes with classes that implement the
LoadunitTestCase
interface, including:
AbstractLoadunitTestCase
: An abstract class that is useful
for creating test cases.
AbstractHTTPTestCase
: An abstract class that provides
functionality for load testing via HTTP.
Loadunit generates two basic types of results: Throughput-Vs-Users data and Performance-Vs-Users data.
Loadunit records the number of tests per second an application can perform for a given number of concurrent users. This number is the throughput that an application can achieve for a given load. It is a measure of how well an application scales. For example, say that you have a test which load tests one Web page. In this case, Loadunit would report the pages/second your Web application could serve for a given number of users.
Following is a sample Throughput-Vs-Users chart that Loadunit generated:
Loadunit records the average test time in milliseconds that an application takes to perform a test for a given number of concurrent users. This number represents how long an application takes to complete a test when under a certain load. It is a measure of how well an application performs. For example, say that you have a test which load tests one Web page. In this case, Loadunit would report the average number of milliseconds your Web application takes to serve that page for a given number of users.
Following is a sample Performance-Vs-Users chart that Loadunit generated:
Loadunit generates reports whenever it runs a Loadunit Suite. You can configure the reports that Loadunit runs by editing the appropriate parameter. You can view a sample report generated by Loadunit's HTMLReporter.
Loadunit supports setting specific failure points for its tests. You can configure a Loadunit test to fail if the test performs too slowly or the test does not scale to a high enough throughput.
To set a LoadunitTestCase
test to fail if it does not reach
a certain throughput, call the method
LoadunitTestCase.setMinThroughput()
.
To set a LoadunitTestCase
test to fail if it takes too
long, call the method LoadunitTestCase.setMaxTime()
.
You must create a loadunit.properties
and place it in your
classpath when running Loadunit. Loadunit comes with a
loadunit.properties.in
file that you can copy and use as a
starting point for setting your Loadunit parameters.
The loadunit.properties
file has the following parameters
you must set:
org.loadunit.report.HTMLReporter
.
This section will walk you through using Loadunit to load test a fictional Web application, ShoppingCart. ShoppingCart is a simple Web application that lets users browse or search for products and add them to a shopping cart. Adding an item to a shopping cart requires a user login.
You can see all the code in this walkthrough in the class,
org.loadunit.example.ShoppingCartSuite
.
First, you must create your LoadunitSuite. Create a class,
ShoppingCartSuite
, that extends
org.loadunit.LoadunitSuite
. Add a
basic constructor that sets the name of the suite:
public class ShoppingCartSuite extends LoadunitSuite { public ShoppingCartSuite() { super("shoppingcart-loadunit-suite"); } }
We'll start by creating a simple test to load test the ShoppingCart home
page. Add the following method to ShoppingCartSuite
:
public static Test homePageTest() { String sURL = "/home"; URLTestCase test = new URLTestCase(sURL); test.setName("HomePageTest"); return test; }
This test tests the home page, which is located at "/home." Notice that the test only specifies a relative URL. This is because Loadunit allows you to set the test site's host name, port, and URL prefix through a properties file. By using a relative URL, you can run the same test on a variety of test machines without modifying your test code.
Notice also that we set the test name. You should always set the test name for reporting purposes.
Now, let's create a test that will load test searching. Add the following method:
public static Test searchTest() { //the base url that doesn't change String sSearchURL="/search.cgi?q="; //the search terms. Each virtual user will randomly select //one of these search times each time it makes a request String[] params = {"linux", "computers", "cars"}; ParameterizedURLTestCase test = new ParameterizedURLTestCase(sSearchURL, params); test.setName("SearchTest"); return test; }
This test uses a ParameterizedURLTestCase
.
ParameterizedURLTestCases
are useful when you want to test
a dynamic Web page that operates differently depending on what
parameters it receives.
In this case, we create a list of search terms. Each virtual user will randomly select a different search term whenever it makes a request. This assures that the server will see varied load patterns under a load test.
Let's say that we want to load test a specific sequence of Web pages. We can do that by adding the following method:
public static Test browseTest() { //navigate to the help contacts String[] URLs = { "/home/", "/help/about", "/help/about/contacts" }; URLSeriesTestCase test = new URLSeriesTestCase(URLs); test.setName("BrowseTest"); return test; }
Finally, we'll create a test that adds an item to a shopping cart.
Remember that this action requires a user login. But, we don't want to
load test the login process--we want to load test adding something to a
shopping cart. How do we do that? We use a preTest()
.
In this case, we'll write a preTest()
to login a user.
Then, we'll write a test()
to add an item to a shopping
cart. Loadunit will run the login preTest once for each virtual user and hold
the resulting login cookie throughout the main test:
public static Test addItemToCartTest() { Test test = new AbstractHTTPTestCase() { //set login cookies using a preTest public void preTest() { String sURL = "/login"; String sUsername = "testuser"; String sPassword = "testpassword"; NameValuePair username = new NameValuePair("username", sUsername); NameValuePair password = new NameValuePair("password", sPassword); clientPostURL(sURL, new NameValuePair[]{ username, password}); } protected void doTest() { //now that we're logged in, load test adding an item to the cart String sURL = "/cart/add"; String sProductID = "235"; NameValuePair product = new NameValuePair("productID", sProductID); clientPostURL(sURL, new NameValuePair[] {product}); } }; ((LoadunitTestCase)test).setName("AddItemToCartTest"); return test; }
Finally, we want to create a ShoppingCartSuite and add the tests we have
just written to it. We will also write a main
method to
run this suite:
public static Test suite() { ShoppingCartSuite suite = new ShoppingCartSuite(); suite.addTest(homePageTest()); suite.addTest(searchTest()); suite.addTest(browseTest()); suite.addTest(addItemToCartTest()); return suite(); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); }
The sample code in the ShoppingCartSuite tests Web pages. However,
Loadunit supports load testing of arbitrary code. If you want to load
test a particular software component, just create a class that
implements the
org.loadunit.LoadunitTestCase
interface and
tests your code. You may want to have your class extend
org.loadunit.AbstractLoadunitTestCase
and
just implement that abstract class's doTest()
method.
Loadunit is licensed under the GPL.