Testing Complex Scenarios
Why do we need to test complex distributed scenarios?
- Tests that verify the integrity of a small unit are useful but limited. Experience has taught us that most bugs are found in the integration phase. These problems range from two modules that fail to work together, all the way to two separate applications that are acting up. Whether it is two application servers, a client/server environment, or even a peer-to-peer scenario, it is highly important to test these complex scenarios because of the tricky bugs that can be found in them. But it is nearly impossible to do so with JUnit.
- Although Java is platform-independent, it is wise to check an application on more than one operating system. Your application may work very well on all operating systems, but it may not function exactly the way you expect it to work on some of them. Running the same set of tests over and over again for every OS is time-consuming, and with JUnit you cannot perform distributed tests, so you don't have a way to run the same series of tests simultaneously on several JVMs each running on different OSes.
- Some units of code can only be tested in a multiple-JVM scenario. For example, testing the opening of a connection (TCP socket or HTTP connection) and the integrity of the information retrieved from it is not possible (or very hard) to test with only one JVM, which is the only option that exists with JUnit.
Coordinating JUnit Tests Using Ant
It is possible to coordinate several tests running on different
JVMs using only JUnit and Ant. Ant can run tasks both serially and
in parallel (using the
<parallel> tag), and can
be configured to stop if any of these tasks fail.
There are several limitations to this approach. First, using JUnit together with Ant still limits you to one box and one operating system. Second, as you accumulate many tests, the Ant XML file grows ever bigger and more unmanageable. Third, we found that in some cases the forked JVMs remained up and running even after the Ant task had terminated.
The Pisces project came into the world because of these limitations and in order to fully equip JUnit with the ability to test complex and distributed scenarios. The next sections of this article will introduce this open source project.
Taking JUnit Out of the Box with Pisces
Project Pisces is an innovative open source project that extends the JUnit framework. Like many other extensions, Pisces adds functionality to JUnit while keeping the way you use it exactly the same.
At the heart of Pisces lies the ability to run JUnit tests on a
remote JVM on the same computer, or on a separate one. These remote
tests are wrapped in JUnit tests that are run locally so that the
developer or QA person performs regular (local) tests using regular
JUnit GUI tools. The wrapper object for the remote tests is called
RemoteTestCase and it extends the
Figure 2 shows the remote test and its wrapper.
Figure 2. The remote test and its wrapper
On every remote location we run a Pisces Agent application with a unique agent name. That agent performs the actual JUnit test and returns the result to the local test. Now, once we can run a remote test wrapped in a local test, we can create a more complex scenario that is composed of several remote tests. Figure 3 shows a test suite composed of several remote tests.
Figure 3. A test suite composed of several remote tests