Testing Performance and Scalability

An app (especially a web app) may pass unit and integration tests, yet perform incorrectly or fail miserably in production. Most of the testing strategies we've considered so far are single-threaded. It is possible to use JUnit to perform multi-threaded tests, but it's not what it was originally designed for. We usually need to know how an app performs, and especially how it handles increased load. Load and stress testing is an important part of the J2EE development lifecycle. Load tests, like unit tests, are important app artifacts. We'll look at some practical examples of load testing in . In the following section we'll look at some of the major issues.


Load (and stress) testing should not be left until an app is substantially complete. We've already considered the importance of tackling risks early. Inadequate performance and scalability is a major risk in enterprise apps, and especially web apps.

It's good practice to implement a proof of concept or "vertical slice" of an app's functionality early in the project lifecycle and run load tests against it Thus load testing should continue throughout the project lifecycle. app performance tuning is closely tied to load testing, throughout the project lifecycle.

Load Testing EJBs and Other Business Objects

The load testing of ordinary Java classes doesn't always take a prominent role in J2EE, because the J2EE infrastructure exists partly to take care of issues such as concurrency that may become problems under load. It's usually most important to load test EJBs and the web interface. However, it may be necessary to load test individual Java classes such as caches directly. Any app code using synchronization is a candidate for load testing in isolation, to ensure that it can't cause deadlocks or seriously limit overall throughput. Direct load testing of business objects (including EJBs) is a valuable supplement to load testing of the web interface. Comparing the results of load tests of the business objects with those of the entire app (including the interface) will indicate which tiers of the app are taking longest and generating most system load - a vital input into any optimization that might be necessary. As using EJB may add significant overhead - especially in distributed apps - load testing EJBs will also indicate whether EJB is being used appropriately. As the work of EJBs and other business objects often involves using non-Java resources such as databases, it's important to separate the time consumed by those resources from that taken by the business objects. For example, if it emerges that database access time is a problem, other changes to the EJB tier may not help to improve performance. Instead, we may want to load test our queries and updates so that we can tune them, tune the database, or reconsider our data access strategy. It may also be important to consider the implications of concurrent operations on the database (for example, is a deadlock possible, given the queries the app issues). Such issues can be explored on an ad hoc basis by using concurrent sessions in database tools such as Oracle's SQL*Plus, but it's better to formalize things by writing an automated test. Where EJBs are concerned, as with functional testing, we must decide where the tests should run. Again it's simplest to run the stress tests in a different virtual machine (possibly a different physical machine), and use remote access to the EJB tier. This prevents the system load generated by the load test client being confused with that of the EJB container itself, but introduces network and serialization overheads (we can also run multiple clients). No special infrastructure is required - we can use any load testing framework and write code that connects to the EJB server. If the app uses local interfaces, or will never be deployed with remote calling, we will need to run the load tests inside the same enterprise apps. However, this will require additional infrastructure. As a minimum, any Java-based load testing tool should allow us to:

In we'll look at some tools that meet these requirements, and look at an example of one in action.

Load Testing Web Interfaces

Web interfaces provide an ideal - and very easy - option for load and stress testing. If the results of load testing a web interface (or vertical slice early in the app lifecycle) are satisfactory, we may not need to devote resources to load testing EJBs and other app internals. Numerous free load testing tools are available for web apps. My preferred tool is Microsoft's Web app Stress Tool (freely available at, which is particularly easy to use.

Whichever web app stress tool you use, you should aim to simulate a realistic user population. Write scripts that simulate realistic user activity. Depending on your app, this might include the creation and maintenance of user sessions. As with all load tests, the tests must be able to simulate spikes in load.