Testing with Arquillian

Arquillian is a test-harness from JBoss that facilitates launching applications and executing test code both from outside and within the running application.

Under traditional usage, Arquillian first launches the application server, then deploys an archive created within your unit test to it. When used with WildFly Swarm, there is obviously no separate launch the application server phase.

Instead, your test-case creates your application, and the Arquillian adapter wraps it with the WildFly Swarm bits and executes the resulting uberjar.

Once it is running, test code may run outside of the uberjar or within it, reporting the test results back to the testing framework.

Configuring

To use the WildFly Swarm Arquillian adapter, you need to add the following into your pom.xml:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.jboss.arquillian</groupId>
      <artifactId>arquillian-bom</artifactId>
      <version>1.1.10.Final</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
<dependencies>
  <!-- Brought in via WildFly Swarm `bom` -->
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>arquillian</artifactId>
    <scope>test</scope>
  </dependency>
  <!-- Brought in via Arquillian BOM, see dependencyManagement section above -->
  <dependency>
    <groupId>org.jboss.arquillian.junit</groupId>
    <artifactId>arquillian-junit-container</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

Writing a Test

To integrate Arquillian into your test, you need to use the JUnit @RunWith annotation and the Arquillian.class test-runner:

@RunWith(Arquillian.class)
public class MyTest {
  ...
}

This integrates the Arquillian lifecycle with the test-case.

Next, you need to specify the deployment that should be wrapped up in the WildFly Swarm mechanism. This is accomplished by using the @Deployment Arquillian annotation on a public static method that returns a ShrinkWrap archive.

@Deployment
public static Archive createDeployment() {
  ...
}

The contents of this method is similar to whatever you would do within your main(…​) method.

For instance:

@Deployment
public static Archive createDeployment() {
    JAXRSArchive deployment = ShrinkWrap.create( JAXRSArchive.class );
    deployment.addResource( MyResource.class );
    return deployment;
}

By default, all methods annotated with @Test will run inside the application. Depending on the functionality you include, you can use annotations such as @Inject (if you’re using CDI) to inject components into your test-case class.

If you wish to test your application from outside (for instance, with a web client), you can use the @RunAsClient annotation on your method.

Example with CDI

@RunWith(Arquillian.class)
public class MyTest {

    @Inject
    private MyComponent component;

    @Test
    public void testMyComponent() {
      // Runs within the application, CDI injects MyComponent

      // assert something about this.component
    }

    @Deployment
    public static Archive createDeployment() {
      JARArchive archive = ShrinkWrap.create( JARArchive.class );

      // ... set up archive ...

      return archive;
    }
}

Example with custom Container configuration

If the swarm container has to be configured (e.g. to configure the DataSource fraction) then this can be done by implementing the ContainerFactory interface.

@RunWith(Arquillian.class)
public class MyTest {
    @Deployment(testable = false)
    public static Archive createDeployment() {
        JARArchive deployment = ShrinkWrap.create(JARArchive.class);
        // ... set up archive ...
        return deployment;
    }

    @CreateSwarm
    public static Swarm newContainer() throws Exception {
        Swarm swarm = new Swarm();
        // ... configure Swarm ...
        return swarm;
    }

    @Test
    @RunAsClient
    public void testNothing() {

    }
}

Default Deployment

In a world of microservices, this tends to not be the case, and the entire "application" represents one small microservice component.

The @DefaultDeployment annotation has been provided to automatically create the deployment of the entire application.

@RunWith(Arquillian.class)
@DefaultDeployment
public class InContainerTest {

Using the @DefaultDeployment annotation provided by WildFly Swarm’s Arquillian integration means you should not use the usual Arquillian @Deployment annotation on a static method returning an Archive.

The @DefaultDeployment annotation looks at the package of the test, and it uses heuristics to include all of your other application classes residing in that package or deeper within the Java packaging hierarchy.

@DefaultDeployment defaults to create a ShrinkWrap WAR archive.

Passing additional options to the -swarm.jar

The Arquillian container for WildFly Swarm supports the following system properties in addition to those listed in the plugin chapter:

Name Description Default

swarm.build.modules

':' separated list of paths to module directories to include

"modules"

swarm.build.repos

',' separated list of repo urls to include when resolving dependencies

swarm.export.uberjar

If true, the test -swarm.jar will be exported to disk to aid debugging

false