With Arquillian we can package a JavaEE application together with a JUnit test case, deploy it to a container and run the test case inside the container. Arquillian is able to pull this off in a platform independent manner. The test code can be completely generic, with no trace of any preparational steps for a specific container. All we need to do is drop a container specific Arquillian adapter on the classpath for the test.
In this post we will build a simple test case and run it inside Apache TomEE 1.7.4 using the Arquillian TomEE remote adapter. Using a remote adapter has the advantage that it is fast because the container is already running. It should be noted that the TomEE's remote adapter is a bit unusual in that it will try to download and start the container if it doesn't find one already running. This would be a desirable feature if one wants to make a self-contained test but it's also going to be slower.
Download either Apache TomeEE 1.7.4 webprofile or plus from http://tomee.apache.org/downloads.html and unzip or untar TomEE.
Add these 3 system properties to apache-tomee-plus-1.7.4/conf/system.properties to enable remote deployment.
$ cd apache-tomee-plus-1.7.4/bin
For the impatient a full Maven project configured to run a simple test case using TomEE's remote adapter is available here:
$ git clone https://github.com/SorenPoulsen/arquillian-tomee-remote.git
Assuming TomEE is running on default ports we can now run the test case with Maven:
$ cd arquillian-tomee-remote
$ mvn clean test
Maven should report success. If instead Maven begins to download TomEE then either the instance we installed in the previous chapter is not running or it's running on non-default ports.
Keep on reading to see how this test project was put together.
First create an empty folder for the Maven project:
$ mkdir arquillian-tomee-remote
Then add a pom.xml in the root of the project with ShrinkWrap and Arquillian dependencies.
Notice that the arquillian-tomee-remote dependency is added through a Maven profile. This is not strictly necessary with only one Arquillian adapter in the project but if we start adding more adapters then we can select between adapters using profiles. Only one adapter can be present on classpath at any one time.
Next we need to configure the TomEE remote adapter. Add a file under /src/test/resources/arquillian.xml with the content shown below. It provides the adapter with the very minimum of information required to deploy to a running TomEE container, namely the port numbers. If we don't provide the port numbers then the TomEE remote adapter will try to download and start a new TomEE container.
How does Arquillian know which container configuration to select from the arquillian.xml file if we add more adapters to the Maven pom file? Looking at the pom.xml file shown previously we find the answer in the tomee-remote profile. A system property named arquillian.launch is passed to Arquillian to select a container in arquillian.xml. Using this mechanism we can pair each new Maven profile (and its respective adapter) with its container configuration in arquillian.xml.
Now let's finish up with the actual test class as shown below. To run JUnit test cases with Arquillian we need two annotations. @RunWith(Arquillian.class) on the test class and a method tagged with @Deployment. The latter method builds the WAR file using ShrinkWrap. Add the classes under test and their dependencies to the WAR, but don't add the JUnit test class itself. Arquillian will actually unpack the WAR file and add the test class plus a number of Enrichers. The Enrichers provide the magic that makes the test class itself a target for CDI and Resource injection among other things.
That wraps it up. The details on the managed bean that is being injected and the web.xml with the Resource configuration are not covered in this post. You can browse the files here https://github.com/SorenPoulsen/arquillian-tomee-remote.