JBoss.orgCommunity Documentation

Chapter 4. Target containers

4.1. Container varieties
4.2. Container management
4.3. Supported containers
4.4. Container configuration

Arquillian's forte is not only in its ease of use, but also in its flexibility. Good integration testing is not just about testing in any container, but rather testing in the container you are targeting. It's all too easy to kid ourselves by validating components in a specialized testing container, only to realize that the small variations causes the components fail when it comes time to deploy to the application for real. To make tests count, you want to execute them in the real container.

Arquillian supports a variety of target containers out of the box, which will be covered in this chapter. If the container you are using isn't supported, Arquillian makes it very easy to plug in your own implementation.

You can run the same test case against various containers with Arquillian. The test class does not reference the container directly, which means you don't get locked into a proprietary test environment. It also means you can select the optimal container for development or easily test the compatibility of your application.

Arquillian recognizes three container interaction styles:

Containers can be further classified by their capabilities. There are three common catagories:

Arquillian provides SPIs that handle each of the tasks involved in controlling the runtime environment, executing the tests and aggregating the results. So in theory, you can support just about any environment that can be controlled with the set of hooks you are given.

While the management of an embedded container is straightforward, you may wonder how Arquillian knows where the remote and managed containers are installed. Actually, Arquillian only needs to know the install path of managed containers (e.g., jbossas-managed-6). In this case, since Arquillian manages the container process, it must have access to the container's startup script. For managed JBoss AS containers, the install path is read from the environment variable JBOSS_HOME.

For remote containers (e.g., jbossas-remote-6), Arquillian simply needs to know that the container is running and communicates with it using a remote protocol (e.g., JNDI). For remote JBoss AS containers, the JNDI settings are set in a jndi.properties file on the classpath. You also have to set the remote address and HTTP port in the container configuration if they differ from the default values (localhost and 8080 for JBoss AS, respectively).

The implementations provided so far are shown in the table below. Also listed is the artifactId of the JAR that provides the implementation. To execute your tests against a container, you must include the artifactId that corresponds to that container on the classpath. Use the following Maven profile definition as a template to add support for a container to your Maven build, replacing %artifactId% with the artifactId from the table. You then activate the profile when executing the tests just as you did in the Chapter 3, Getting started chapter.


<profile>
   <id>%artifactId%</id>
   <dependencies>
      <dependency>
         <groupId>org.jboss.arquillian.container</groupId>
         <artifactId>%artifactId%</artifactId>
         <version>${arquillian.version}</version>
      </dependency>
   </dependencies>
</profile>

Support for other containers is planned, including Weblogic (remote), WebSphere (remote) and Hibernate.

You can come a long way with default values, but at some point you may need to customize some of the container settings to fit your environment. We're going to have a look at how this can be done with Arquillian. Arquillian will look for a file named arquillian.xml in the root of your classpath. If it exists it will be auto loaded, else default values will be used. So this file is not a requirement.

Lets imagine that we're working for the company example.com and in our environment we have two servers; test.example.com and hudson.example.com. test.example.com is the JBoss instance we use for our integration tests and hudson.example.com is our continuous integration server that we want to run our integration suite from. By default, Arquillian will use localhost, so we need to tell it to use test.example.com to run the tests.


<?xml version="1.0"?>
    
<arquillian xmlns="http://jboss.com/arquillian"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jboss="urn:arq:org.jboss.arquillian.container.jbossas.remote_6">

 <engine>
   <deploymentExportPath>/tmp</deploymentExportPath>
 </engine>
    
 <jboss:container>
   <jboss:remoteServerAddress>test.example.com</jboss:remoteServerAddress>
   <jboss:remoteServerHttpPort>8181</jboss:remoteServerHttpPort>
   <jboss:localDeploymentBindAddress>
    hudson.example.com
   </jboss:localDeploymentBindAddress>
   <jboss:localDeploymentBindPort>7000</jboss:localDeploymentBindPort>
 </jboss:container> 

</arquillian>

That should do it! "Each type of container has it's own XML namespace for configuration - here we use the JBoss AS 6.0 Remote container. Each container has different configuration options. Next step is to create a container element in that namespace and add the options you want to configure inside. In this example we're saying that the server we want to test against can be found on address test.example.com using port 8181, and the remote server can communicate back to us on address hudson.example.com on port 7000. Some containers expect to be given a URL from which they can retrieve the application to be deployed. For these containers, Arquillian will start a local HTTP server.

Warning

Some containers require a jndi.properties file on classpath with the containers standard JNDI properties for the initial connection.