In container testing

One of the main difficulties I have ran into while testing j2ee applications is distributing tests and test decorators ­ fixtures, probes - for execution in environments identical to those where the code will be executed during production. This technique, called in container testing, is essential in ensuring a reasonable level of confidence in the tested j2ee code. In container testing is often very difficult to implement because mainstream java testing frameworks don't support it out of the box. Some have extensions that support it, but that support is far from being complete.

Why is in container testing so important? The J2EE code we write may be executed in, and invoked from a large variety of environments. A stateless session bean for example, can be called from within a SERVLET container, from within another EJB, a JMS listener or from a client JVM. If we want to test it properly, we should write a test case for each environment from where the component may be called. For efficiency reasons we should be able to write the test case only once, and then somehow instruct the testing framework to execute the test case in each required environment. This should be possible since in every such case the test logic is the same, only the container in which the test is executed varies.

The same principles can also be applied to test decorators. In integration testing, we often need to write fixtures that manage a distributed data configuration. Maybe a directory structure has to be created on the machine running the application server or maybe some database tables needs to be populated with objects and we want/need to do it through a j2ee data source. We should be able to concentrate on the code that creates and tears down the test environment and let the testing framework coordinate execution of test decorators in various containers.

In order to address all these issues, the TESTARE testing framewrok introduces the concept of “execution scenario”, as a way to implement in container testing. An execution scenario for a test case or for a test case decorator is specified by implementing a marker interface. The marker interface declares a scenario runner. When the test case and its decorators are executed, the testing framework uses introspection to determine which scenarios ­ marker interfaces ­ are implemented and delegates the execution to the declared scenario runner(s).

The floating scenario

Fixtures, test guards and test environment probes can also implement a special type of execution scenario, called the “floating” scenario. Floating means that the test decorator is executed in the same container as the test case itself. This is a very useful feature for in container testing situations when the test environment must be set up, guarded or probed at the location where the test code is executed ­ like manipulating a file on the local file system or accessing singleton data from the jvm where the test case is executed.

Default execution scenarios

By default, TESTARE comes with a range of pre-implemented execution scenarios for test cases and test case decorators.

  1. Execution scenarios available for test cases:

    1. ClientSideTest ­ executes test cases in the same client JVM where the testing framework is executed

    2. EjbNoTransactionTest ­ executes test cases in an ejb container, with no ongoing j2ee transaction - this is part of TESTARE's in ejb container testing support

    3. EjbUserTransactionTest ­ executes test cases in an ejb container, in the context of a user demarcated j2ee transaction - this is part of TESTARE's in ejb container testing support

    4. EjbContainerTransactionTest ­ executes test cases in an ejb container, in the context of a container demarcated j2ee transaction - this is part of TESTARE's in ejb container testing support

  2. Execution scenarios available for fixtures:

    1. ClientSideFixture ­ the fixture's setUp and tearDown method are executed in the same client JVM as the testing framework.

    2. FloatingFixture ­ the testing framework will execute the fixture in the same environment / container in which the test itself is executed<.

    3. EjbFixture ­ the fixture's setUp and tearDown methods are called from within an ejb container - this is part of TESTARE's in ejb container testing support

  3. Execution scenarios available for global fixtures:

    1. ClientSideGlobalFixture ­ the global fixture's setUp and tearDown method are executed in the same client JVM as the testing framework.

    2. EjbGlobalFixture - the global fixture's setUp and tearDown methods are called from within an Ejb container - this is part of TESTARE's in ejb container testing support.

  4. Execution scenarios available for test environment probes:

    1. ClientSideTestProbe ­ the probe will be used to investigate the client JVM in which the testing framework runs

    2. FloatingTestProbe ­ the testing framework will execute the probe in the same environment / container in which the test itself is executed<

    3. EjbTestProbe ­ the probe is used to investigate an ejb container - this is part of TESTARE's in ejb container testing support.

  5. Execution scenarios available for test environment guards:

    1. ClientSideTestGuard ­ the guard is used to validate the client JVM in which the testing framework runs

    2. EjbTestGuard - the guard is used to validate an ejb container - this is part of TESTARE's in ejb container testing support.

    3. FloatingTestGuard - the testing framework will execute the guard in the same environment / container in which the test itself is executed

Remember that only test cases can implement more then one scenario at a time. Decorators can only implement one execution scenario at a time.