How To Use Arquillian(update)

Arquillian is an integration and functional testing framework for JavaEE and i always connect it with the phrase Write real world tests. But what does it mean exactly? What is a real world test?

For me real world test means that the execution environment is the same (or as near as possible) to my production environment and exactly that is what Arquillian provides.

The only drawback i found so far is that it does not work with standard JUnit Parameterized but this is more related to JUnit since it does not allow more than one runner per test class. Usually this restriction is overcome by implementing the functionality as JUnit Rule and fortunately there are two already:

I also had some discussions about performance of Arquillian tests which are by nature a little bit slower than plain JUnit tests. The standard argument is slow startup time of the containers. But for one thing almost every container (incl. application servers) starts up within seconds and usually performance on a Jenkins is of secondary importance. During development it is recommended to use a remote container so that start up time does not apply anymore.

One important question for me is when to use a framework or tool and when not to use it. From my point of view Arquillian can be used in almost any case except for DAO tests. Sure it works and does not look bad but for me it feels a little bit heavy weight. Especially in comparison with Rulz of Adam Bien it looks a little bit strange.

Further information about Arquillian can be found on the Arquillian website.

Containers

Since i always forget some of the differences between different container types the following diagram serves as a helper.

Info:

The specific container provider can be divided further into the following three groups:

Usage

In order to run an Arquillian test you need to do the following three steps:

 1 <plugin>
 2       <artifactId>maven-surefire-plugin</artifactId>
 3       <version>2.19</version>
 4      <configuration>
 5          <systemPropertyVariables>
 6                 <!-- reference to arquillian.xml container -->
 7                 <arquillian.launch>arquillian-wildfly-managed</arquillian.launch>
 8             </systemPropertyVariables>
 9      </configuration>
10     </plugin>
1 @Stateless
2 public class ServiceFacade {
3     public String getHello() {return "hello";}
4     public String getPrint() {return "print";}
5 }
 1 @RunWith(Arquillian.class)
 2 public class ServiceFacadeHelloTest {
 3 
 4     @Inject ServiceFacade serviceFacade;
 5 
 6     @Deployment
 7     public static WebArchive create() {
 8            
 9             //testHello and testPrint are using assertj 
10             //therefore the container needs to know it
11             File[] libs = Maven.resolver()
12                                .loadPomFromFile("pom.xml")
13                                .resolve("org.assertj:assertj-core")
14                                .withTransitivity().as(File.class);
15     
16             return ShrinkWrap.create(WebArchive.class, "mytest.war")
17                 .addAsLibraries(libs)
18                 .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
19                 .addClass(ServiceFacade.class);
20     }
21 
22     @Test
23     public void testHello() {
24         assertThat(serviceFacade.getHello()).isEqualTo("hello");
25     }
26 
27     @Test
28     public void testPrint() {
29         assertThat(serviceFacade.getPrint()).isEqualTo("print");
30     }
31 }

The snippet above is testing a simple session bean with AssertJ via Arquillian. The important part for using Arquillian is:

  1. Declare Arquillian JUnit runner with @RunWith(Arquillian.class)
  2. Provide an archive with a static method marked with @Deployment which is then deployed to the container. In this case ShrinkWrap is used to create a web archive which contains the AssertJ library, an empty beans.xml and the ServiceFacade.

Note: JBoss Forge provides already the arquillian-addon.

The following repository contains a working example for three wildfly arquillian containers: embedded, managed and remote.