JBoss.orgCommunity Documentation
This chapter walks through some more advanced features and use cases you can have Arquillian do for you.
We have previously seen Arquillian deploy ShrinkWrap Archives, but some times you need to deploy other items like a JMS Queue or a DataSource for your
test to run. This can be done by using a ShrinkWrap sub project called ShrinkWrap Descriptors. Just like you would deploy a Archive
you can
deploy a Descriptor
.
@Deployment(order = 1)
public static Descriptor createDep1()
{
return Descriptors.create(DataSourceDescriptor.class);
}
@Deployment(order = 2)
public static WebArchive createDep2() {}
@Test
public void testDataBase() {}
When dealing with multiple different environments and hidden dynamic container configuration you very soon come to a point where you need
access to the backing containers ip/port/context information. This is especially useful when doing remote end point testing. So instead of trying
to setup all containers on the same ip/port/context, or hard code this in your test, Arquillian provides something we call @ArquillianResource
injection. Via this injection point we can expose multiple internal object.
When you need to get a hold of the HTTP context your Deployment
defined, you can use @ArquillianResource
on
a field or method argument of type URL.
@ArquillianResource
private URL baseURL;
@ArquillianResource(MyServlet.class)
private URL baseServerURL;
@Test
private void shouldDoX(@ArquillianResource(MyServlet.class) URL baseURL)
{
}
Sometimes a single Deployment
is not enough, and you need to specify more then one to get your test done. Maybe you want to
test communication between two different web applications? Arquillian supports this as well. Simple just add more @Deployment
methods to the test class and your done. You can use the @Deployment.order
if they need to be deployed in a specific order.
When dealing with multiple in container deployments you need to specify which Deployment
context the individual test methods
should run in. You do this by adding a name to the deployment by using the @Deployment.name
and refer to that name
on the test method by adding @OperateOnDeployment("deploymentName")
.
@Deployment(name = "dep1", order = 1)
public static WebArchive createDep1() {}
@Deployment(name = "dep2", order = 2)
public static WebArchive createDep2() {}
@Test @OperateOnDeployment("dep1")
public void testRunningInDep1() {}
@Test @OperateOnDeployment("dep2")
public void testRunningInDep2() {}
There are times when you need to involve multiple containers in the same test case, if you for instance want to test clustering.
The first step you need to take is to add a group
with multiple containers to your Arquillian configuration.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<group qualifier="tomcat-cluster">
<container qualifier="container-1" default="true">
<configuration>
<property name="tomcatHome">target/tomcat-embedded-6-standby</property>
<property name="workDir">work</property>
<property name="bindHttpPort">8880</property>
<property name="unpackArchive">true</property>
</configuration>
<dependencies>
<dependency>org.jboss.arquillian.container:arquillian-tomcat-embedded-6:1.0.0.Alpha5</dependency>
<dependency>org.apache.tomcat:catalina:6.0.29</dependency>
<dependency>org.apache.tomcat:coyote:6.0.29</dependency>
<dependency>org.apache.tomcat:jasper:6.0.29</dependency>
</dependencies>
</container>
<container qualifier="container-2">
<configuration>
<property name="tomcatHome">target/tomcat-embedded-6-active-1</property>
<property name="workDir">work</property>
<property name="bindHttpPort">8881</property>
<property name="unpackArchive">true</property>
</configuration>
<dependencies>
<dependency>org.jboss.arquillian.container:arquillian-tomcat-embedded-6:1.0.0.Alpha5</dependency>
<dependency>org.apache.tomcat:catalina:6.0.29</dependency>
<dependency>org.apache.tomcat:coyote:6.0.29</dependency>
<dependency>org.apache.tomcat:jasper:6.0.29</dependency>
</dependencies>
</container>
</group>
</arquillian>
So what we have done here is to say we have two containers that Arquillian will control, container-1 and container-2.
Arquillian will now instead of starting up one container, which is normal, start up two. In your test class you can target
different deployments against the different containers using the @TargetsContainer("containerName")
annotation on
your Deployment
methods.
@Deployment(name = "dep1") @TargetsContainer("container-1")
public static WebArchive createDep1() {}
@Deployment(name = "dep2") @TargetsContainer("container-2")
public static WebArchive createDep2() {}
@Test @OperateOnDeployment("dep1")
public void testRunningInDep1() {}
@Test @OperateOnDeployment("dep2")
public void testRunningInDep2() {}
We now have a single test class that will be executed in two different containers. testRunningInDep1
will
operate in the context of the dep1
deployment which is deployed on the container named container-1
and
testRunningInDep2
will operate in the context of deployment dep2
which is deployed on container
container-2
. As the test moves along, each method is executed inside the individual containers.
A protocol is how Arquillian talks and executes the tests inside the container. For ease of development and configuration a container defines a
default protocol that will be used if no other is specified. You can override this default behavior by defining the @OverProtocol
annotation on your @Deployment
method.
@Deployment @OverProtocol("MyCustomProtocol")
public static WebArchive createDep1() {}
@Test
public void testExecutedUsingCustomProtocol() {}
When testExecutedUsingCustomProtocol
is executed, instead of using the containers default defined protocol, Arquillian will use
MyCustomProtocol
to communicate with the container. Since this is defined on Deployment
level, you can have
different test methods operate on different deployments and there for be executed using different protocols. This can be useful when for instance a
protocols packaging requirements hinder how you define your archive, or you simply can't communicate with the container using the default protocol
due to e.g. fire wall settings.