Thursday, October 09, 2008

JBoss EJB3 Integration testing with Maven2 and Cargo

One of the most boring things in EJB development is that we need container. Compile-Build-Deploy-Run_some_testing_code - this is to long cycle to repeat it frequently without some kind of automation. I'll show you one of the possible ways to simplify this stuff. There are others, but I didn't tried them (I mean jboss microcontainer here). It's not complex, but it works and probably could be portable solution for not only my case.

So, my working environment is the following : Maven 2, JBoss 4.2.2 GA, jUnit 3.8.1 and of course EJB3. Build lifecycle with Maven 2 consists of some phases, like "...compile,test,package,integration-test...". Ok, with package and compile phases all is clear. Test... we need jboss to be up and running before we can test anything. How to start and stop jboss automatically during build ? The answer is Cargo with Maven2 plugin.

Cargo is a thin wrapper around existing containers (e.g. J2EE containers). It provides different APIs to easily manipulate containers.

Now we can assign "start container" and "stop container" goals to some Maven 2 build phase. First of all, we are interested in integration-test. Also we need to skip junit tests before integration test. To achieve this I'm using this config for cargo plugin :

<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>0.3-SNAPSHOT</version>
<configuration>
<container>
<containerId>jboss4x</containerId>
<home>${jboss.home}</home>
<append>false</append>
</container>
<configuration>
<type>existing</type>
<home>${jboss.home}/server/default</home>
<properties>
<cargo.jboss.configuration>default</cargo.jboss.configuration>
<cargo.rmi.port>1099</cargo.rmi.port>
<cargo.logging>high</cargo.logging>
</properties>
</configuration>
<wait>false</wait>
</configuration>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>

And this for surefire - to be able to run junit tests on integration-test phase, after container started at pre-integration-test phase :

<plugin>                                      
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>surefire-it</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
I haven't any luck with "standalone" type configuration. I should say that when"existing" jboss installation is used here, overall process is quite fast:

[INFO] -------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] -------------------------------------------
[INFO] Total time: 42 seconds
[INFO] Finished at: Thu Oct 09 15:15:39 EEST 2008
[INFO] Final Memory: 9M/19M
[INFO] -------------------------------------------
42 seconds to compile code, package jar, copy jar to deploy dir, start jboss, run junit test, stop jboss and all this by doing just "mvn install" !

Complete source code available via svn here.

PS.
Time can be very different. My hardware is HP 6820s laptop. BTW, executing "mvn -o install" takes 23 sec :)

5 comments:

shinekanamala said...
This comment has been removed by the author.
shinekanamala said...

Thanks,Good one.It gave me a good start.

Dmitry said...

I was actually trying to test EJB3 entities using in-memory HSQLDB along with sql-maven-plugin.
The only issue is test PersistenceManager (I use Hibernate one for unit-tests) can't find tables I set up by the sql-maven-plugin.
Original config for sql plugin was to set up DB in process-test-classes phase.
But Surefire seems to run tests in a separate JVM (?) and thus HSQLDB is completely new for the execution.
Or it may be standard Maven approach to the lifecycle processing.

I tried to bind sql plugin to the test phase but it's not run before Surefire.

Do you have any idea how to configure a third-party plugin to run in the test phase but before Surefire?

mostro said...

I don't see this as a entire solution. Where, in your configuration, do you deploy your bean in jboss BEFORE doing the integration tests?

louis said...

Thank you, this saved me a lot of time after many tries ...