How can a single Arquillian test be executed in different containers? How does Arquillian decide which container to target? And how are both remote and local invocations supported?
The answers to these question touch on the extensibility of Arquillian.
Container selection occurs at runtime. Arquillian selects the target container according to which container adapter is available on the runtime classpath at the time the test is launched. Therefore, you must include the container adapter as a test-scoped dependency that corresponds to the container you want to target.
Arquillian delegates to an SPI (Service Provider Interface) to handle starting and stopping the server and deploying and undeploying archives. In this case, the SPI is the interface org.jboss.arquillian.spi.client.DeployableContainer. If you recall from the getting started guide, we added an Arquillian container adapter according to the target container we wanted to use. That library contains an implementation of this interface, thus controlling how Arquillian handles deployment.
If you want to add support for another container in Arquillian, you need to provide an implementation of the DeployableContainer interface.
To switch to another container, you just change which container adapter is on the classpath before running the test.
You can only have one container adapter on the classpath at a time. The execution of the test will be aborted if more than one adapter is detected.
One way to swap the libraries on the classpath is to manually edit the dependencies defined in the pom.xml each time. But that’s just tedious. The recommended approach is to use Maven profiles.
Maven profiles allow you to partition your dependencies into groups, one group for each container adapter and its related artifacts. When running the tests, you activate one of those groups, which in turn selects a target container. The profile is activated either using either a commandline flag (-P) or a preference in the IDE.
The Getting Started Guide explains how to setup and use Maven profiles for this purpose in more detail.
So far we've covered how a container adapter is selected. It's also possible to configure the container adapter, which we'll look at next.