Last month I decided to add a touch of microservices to the JEE course I teach at the University of Geneva. I ended up with a couple of microservices and as expected I came across the challenge of their integration testing. This post is specifically about microservices. It rathers focuses on the JEE integration testing experience I encountered while building the microservices. A dedicated blog post will follow on my journey through the building of microservices with JEE.
A short description of the architecture
From a technological perspective, I am using JEE 7 on Wildfly with MySql. Therefore, my microservices are wars composed of 1-2 EJBs plus a restful service that exposes the logic. Typically, my microservices are composed of 4-5 classes of max 150 lines of codes each. On my laptop, a microservice deploys in less than 5 seconds. I mainly need to test EJBs and their database calls. I also want to test integration between microservices.
As it serves as a example for a course, I want it to be super easy to install/re-install 20 times if necessary. Furthermore, I want fast-paced deployment. To that end, Docker is a great tool because I do not have to bother on what laptop/computer the students work (provided they can run Docker Toolbox). Moreover, all the tools/middlewares I am using for the course are already packaged as Docker images.
Building a Docker image for a Wildfly Integration Test Server
As mentioned previously, I propose to use Wildfly + MySql as the runtime environment. However, at test time, I do not want to start both an application server and a database. More important, I want to get a fresh database for each and every test suite. Futhermore, I would like to use on a simpler setup for the application server. For instance, I do prefer to use an in memory H2 database instead of MySql. I also do not want to bother with LDAP/JAAS configuration, clustering, etc…. Of course, datasource name, realm name and more generally all the resources required by the microservices must be present with their production name.
Ones of Wildfly’s great features is its ability to be configured using the command line. The first step is to configure a data source relying on H2 that has the same name as the production one.
Then, let’s configure a realm. This is helpful when integration tests rely on principals and do verify the security.
jee7-demo-realm-roles.properties) defines the users (resp. the roles) of the realm.
1 2 3 4 5 6 7
Finally, let’s add an admin user in order to allows Arquilian or an IDE to interact with this application server.
Hereafter the complete configuration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
The next step is to enhance the official Wildfly image called
jboss/wildfly:latest with the specific configurations required for integration testing. This following Dockerfile describes how to build the image that we will use for testing.
First, it adds the previous configuration files
./config_wildfly.sh ./jee7-demo-realm-roles.properties ./jee7-demo-realm-users.properties to the
/opt/jboss/wildfly/customization/ of the image. Then we tell Docker to run the configuration
config_wildfly.sh and to do some cleanup. After what, it will record the states as a new image.
1 2 3 4 5 6 7 8
Now we can build an image called
jee7-test-wildfly using the following command (in the directory where the
The following command runs the image we just built, exposes (and map) the port 8080, 9090 and 8787, and mount the local directory
/Users/XXXXXXXXXX/tmp/docker-deploy on the image’s
/opt/jboss/wildfly/standalone/deployments/ directory. This is of course the directory in which the integration tests are to be deployed..
Now that we do have a container running an application server with in memory database and a simple realm, we can configure the test harness.
How to configure Arquillian
Arquillian is a JEE integration test framework. It allows to test JEE components such as EJBs or web services.
The first step it to tell Arquillian where the Wildfly server lives. The following
arquillian.xml file states that the integration tests should deploy on a Wildfly container that listens at
192.168.99.100 (which is the Docker container address) on port
9990 (which is the administration port). Furthermore, it declares the admin username and password.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
A simple integration Test
Let us now write a simple integration test. First, we must tell Arquillian the it is in charge of running the test (
To test a given component (let’s say an EJB), arquillian expects a well-formed Java component (either a jar or a war).
The following test is composend of a package contaning the EJB under test (
ch.demo), an empty
beans.xml to enable CDI and finally a
persistence.xml to enable JPA.
1 2 3 4 5 6
The previous JAR as well as the tests are packaged as a WAR and deployed on the application server declared in the
arquillian.xml file. The following test injects the EJB under test implementing the
StudentService interface and tests its
1 2 3 4 5 6 7 8 9 10 11
Maven, IDE Integration and Coverage
Finally, let me add that it is possible to get coverage data from Arquillian by enabling extensions. In the following, it enables
`jacoco. This produces coverage data that can be used by the Eclipse ECL-EMMA plugin.
1 2 3
Docker and Arquillian provide a nice and seamless way for JEE integration testing. Nevertheless, I had a hard time at the beginning because Arquillian error handling in case of undeployable test archive is not very good. In this case, make sure that you package your test correctly (in the method annotated
@Deployment). In particular, double check
web.xml and the JAR/WAR structure. It really helped me to unzip the deployed test archive to figure out what when wrong in my code.