[#testing-in-a-container]
= Testing in a container

Using Arquillian, you have the capability of injecting unit tests into a
running application. This allows you to verify your application is behaving
correctly. There is an adapter for WildFly Swarm that makes Arquillian-based
testing work well with WildFly Swarm{ndash}based applications.

.Prerequisites

* A Maven-based application with a `pom.xml` file.

.Procedure

. Include the WildFly Swarm BOM as described in xref:using-a-bom[]:
+
[source,xml]
----
<dependencyManagement>
  <dependencies>
include::pom.xml[tag=bom,indent=4]
  </dependencies>
</dependencyManagement>
----

ifdef::product[]
. If your test uses the Apache HTTP Client or the JAX-RS Client, add the `commons-logging` artifact to the `test` scope of the project in the `pom.xml` file:
+
--
[source,xml]
----
<project>
  <dependencies>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
      <scope>test</scope>
    <dependency>
  </dependencies>
</project>
----

The reason is that the WildFly Swarm productized rutime artifact BOM imports the EAP runtime artifacts BOM (`org.jboss.bom:eap-runtime-artifacts`), which excludes the `commons-logging` artifact from the `org.apache.httpcomponents:httpclient` and `org.apache.james:apache-mime4j` artifacts.
As a result, when running tests in a Maven project that imports the WildFly Swarm productized runtime artifact BOM, neither the Apache HTTP Client nor any other artifact that depends on it (for example, the JAX-RS Client) works.
--
endif::[]

. Reference the `org.wildfly.swarm:arquillian` artifact in your `pom.xml` file
with the `<scope>` set to `test`:
+
[source,xml]
----
<dependencies>
include::pom.xml[tag=arquillian,indent=2]
</dependencies>
----

. Create your Application.
+
Write your application as you normally would; use any default
`project-defaults.yml` files you need to configure it.
+
[source,yml]
----
include::src/main/resources/project-defaults.yml[]
----

. Create a test class.
+
NOTE: Creating an Arquillian test before WildFly Swarm existed usually involved
programatically creating `Archive` due to the fact that applications
were larger, and the aim was to test a single component in isolation.
+
[source,java]
----
include::src/test/java/org/wildfly/swarm/howto/incontainer/InContainerTest.java[tag=classdef,indent=0]
----

. Create a deployment.
+
--
In the context of microservices, the entire application represents one small
microservice component.

Use the `@DefaultDeployment` annotation to automatically
create the deployment of the entire application. The `@DefaultDeployment`
annotation defaults to creating a `.war` file, which is not applicable in
this case because Undertow is not involved in this process.

Apply the `@DefaultDeployment` annotation at the class level of a JUnit test,
along with the `@RunWith(Arquillian.class)` annotation:

[source,java]
----
include::src/test/java/org/wildfly/swarm/howto/incontainer/InContainerTest.java[tag=prolog,indent=0]
----

Using the `@DefaultDeployment` annotation provided by Arquillian integration
with WildFly Swarm means you should _not_ use the Arquillian `@Deployment`
annotation on static methods that return an `Archive`.

The `@DefaultDeployment` annotation inspects the package of the test:

[source,java]
----
include::src/test/java/org/wildfly/swarm/howto/incontainer/InContainerTest.java[tag=package,indent=0]
----

From the package, it uses heuristics to include all of your other application
classes in the same package or deeper in the Java packaging hierarchy.

Even though using the `@DefaultDeployment` annotation allows you to write tests
that only create a _default deployment_ for sub-packages of your application,
it also prevents you from placing tests in an unrelated package, for example:

[source,java]
----
package org.mycorp.myapp.test;
----
--

. Write your test code.
+
--
Write an Arquillian-type of test as you normally would, including using
Arquillian facilities to gain access to internal running components.

In the example below, Arquillian is used to inject the `InitialContext` of the
running application into an instance member of the test case:

[source,java]
----
include::src/test/java/org/wildfly/swarm/howto/incontainer/InContainerTest.java[tag=arquillian-resource,indent=0]
----

That means the test method itself can use that `InitialContext` to ensure the
Datasource you configured using `project-defaults.yml` is live and available:

[source,java]
----
include::src/test/java/org/wildfly/swarm/howto/incontainer/InContainerTest.java[tag=test,indent=0]
----
--

. Run the tests.
+
Because Arquillian provides an integration with JUnit, you can execute your
test classes using Maven or your IDE:
+
[source,shell]
----
$ mvn install
----
+
NOTE: In many IDEs, execute a test class by right-clicking it and selecting `Run`.

.Related Information

* xref:using-a-bom[]

