Thursday, October 14, 2010

J2EE application on RAD/WebSphere with Maven: Integration testing and other problems

Integration testing of a J2EE application with Maven was unexpectedly hard to get right, although, having got there, the end result seems very logical and almost intuitive.

The reason is probably that (1) there is no single "right" solution, (2) the task is out of the tool's "comfort zone", and (3) doing it requires really wrapping one's head around Maven's life cycle. After having spent several years -- off and on -- using the tool, it turned out I still had some understanding to acquire with (3). But, after the fact, the whole thing seems very straightforward, because it really is.

So. Given: a typical J2EE application being built as an EAR to be deployed on WebSphere, consisting of a library JAR, an EJB JAR, a Web application (WAR), and a test web application with Cactus tests for the EJBs and servlets. The application is built with Maven 2.7 and needs to deploy on WebSphere 6.1.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.rbc.eca</groupId>
  <artifactId>J2eeProto</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>

  <modules>
    <module>../J2eeProto-EAR</module>
    <module>../J2eeProto-lib</module>
    <module>../J2eeProto-ejb</module>
    <module>../J2eeProto-web</module>
  </modules>
  ...

We need: the level of build automation that would allow for automatically building the application, deploying it on a WebSphere server, and running the integration tests. In real life the sequence would be run by a continuous integration server (e.g. Hudson).

The sequence of steps that need to happen is as follows:

(1) build
(2) run unit tests
(3) deploy on test server
(4) run integration tests

The problem: Maven life cycle is geared towards a project that falls short of J2EE 1.4 (EJB 2.1) and builds a WAR file that can be unit tested, bundled, deployed, integration tested inside a single project. However, building an EAR for WebSphere requires a modular J2EE project; Maven life cycle acts on a single project.


So we need to

(1) separate unit tests in all projects from integration tests

(2) build for integration testing (adding Cactus instrumentation where applicable)

(3) run unit tests in all projects (but not integration tests) when building (up to the "package" phase of Maven's life cycle), and apply coverage reporting and the rest

(4) if packaging succeeds, prepare the resulting artifacts for deployment (this needs running application server-specific tasks -- WebSphere-specific, in our case) and deploy them (since we are doing this for automated testing, we need to stop the server, un-deploy and deploy the EAR, and start the server to diminish the number of things that could break as the application changes)

(5) run the integration tests in all projects, with the appropriate test reporting

To be continued:

No comments: