Manage Server Resources with Arquillian

Arquillian has support for multiple injection points like @EJB, @Resources and @Inject, but there are also non standard component model objects available within the Arquillian runtime that can be of useful during testing. In this tutorial we will learn how to expose these objects to the test case using the @ArquillianResource injection annotation.

 

By using the @ArquillianResource injection you can expose multiple internal objects such as Containers or Deployments which will be handled programmatically by your Test case.

Let’s see an example of it:

package com.itbuzzpress.chapter8.test;


import java.util.List;

import org.jboss.arquillian.container.test.api.*;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.Before;
import org.junit.Test;

import javax.inject.Inject;

import static org.junit.Assert.*;

import org.jboss.arquillian.junit.Arquillian;

import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;

import org.junit.runner.RunWith;

import com.itbuzzpress.chapter8.ejb.ManagerEJB;
import com.itbuzzpress.chapter8.entity.Customer;
import com.itbuzzpress.chapter8.entity.Request;
import org.jboss.arquillian.junit.InSequence;
 
@RunAsClient
@RunWith(Arquillian.class)

public class TestJPA {

 @Inject ManagerEJB ejb;

 @ArquillianResource
 private ContainerController controller;

 @ArquillianResource
 private Deployer deployer;

 @Before
 public void before() throws Throwable {
  System.out.println("Before Test");
 }
 @Deployment(name = "deploy-0", managed = false)
 @TargetsContainer("node-0")

 public static Archive < ? > createTestArchive() {
  return ShrinkWrap.create(WebArchive.class, "testjpa.war")
   .addPackage(Customer.class.getPackage())
   .addPackage(ManagerEJB.class.getPackage())
   .addAsResource("META-INF/persistence.xml")
   .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");


 }

 @Test
 @InSequence(-1)
 public void startServer() {
  controller.start("node-0");
  deployer.deploy("deploy-0");
 }


 @Test
 @InSequence(1)
 public void stopServer() {
  deployer.undeploy("deploy-0");
  controller.stop("node-0");


 }

 @Test
 public void test() {
  try {

   ejb.createCustomer("john", "park avenue 125", "jsmithATgmail.com", "+3955555");
   Customer customer = ejb.findCustomerByName("john");
   List < Customer > cc = ejb.findAllCustomers();
   System.out.println(cc);
   assertNotNull(customer);
   ejb.createRequest("john", 100);

   List < Customer > customerList = ejb.findAllCustomers();

   log("=======> Customer List ");
   for (Customer c: customerList) {
    log("Customer found: " + c);
    log("============> Request Accociated:");
    List < Request > requestList = ejb.findAllRequestsByCustomer(c.getName());
    for (Request r: requestList) {
     log("Request found: " + r);
    }
   }

  } catch (Exception e) {
   System.out.println(e.getClass());
   // TODO Auto-generated catch block
   e.getMessage();
  }
 }

 private void log(String string) {
  System.out.println(string);

 }

}

This Test class is derived from the TestJPA class contained in the Practical Java EE Development with WildFly. Compared with the source code available on github (https://github.com/fmarchioni/practical-javaee7-development-wildfly/tree/master/code/chapter8/javaee7-test) we have changed a couple of things:

First of all, the application server is not started/stopped automatically by Arquillian but you can control it by injecting the Application server as an @ArquillianResource:

@ArquillianResource
private ContainerController controller;

Next, also the Deployment of applications is managed programmatically by injecting another @ArquillianResouce:

@ArquillianResource
private Deployer deployer;

Finally, notice that in order to guarantee that the @Test are run in the proper order (at first the application server is started, then the application is deployed and finally the test() method is executed), we have decorated our @Test with @Insequence annotation:

@Test
@InSequence

As you can see, we have referenced our Container by using the node-0 alias. This needs to be defined in arquillian.xml where you specify the Container type and configuration:

<arquillian xmlns="http://jboss.org/schema/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">

	<defaultProtocol type="Servlet 3.0" />

	<container qualifier="node-0" mode="manual" default="true"  >

		<configuration>
			<property name="jbossHome">/home/jboss/wildfly-12.0.0.Final</property>
			<property name="managementPort">9990</property>
			<property name="managementAddress">localhost</property>
		</configuration>

	</container>

</arquillian>

How to test with Arquillian, Chameleon and JBoss Forge

In this tutorial we will learn how to set up quickly a test for our Java EE project using Arquillian, Chameleon and JBoss Forge to scaffold our project.

 

First of all some definitions about the tools we will use:

  • JBoss Forge is a software development tool that extends your Java IDE, providing wizards and extensions (add-ons) for different technologies and solutions.
  • Arquillian is an integration testing framework for Java EE which works on any Java Enterprise container.
  • Chameleon is an abstraction Container which works on the top of Arquillian so that you can easily switch from ona Container implementation to another.

To get started, just download JBoss Forge (or if you have JBoss Developer Studio then you already have it in your IDE).

Create the Java EE Project

$ forge

Let’s create a sample project which uses JAVA_EE_7 stack:

project-new  --named demo-forge --type war --stack JAVA_EE_7

As it is, the project merely contains a pom.xml with the Java EE dependencies:

    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <scope>provided</scope>
    </dependency>

Let’s add a CDI Bean to the project so that we can use it for testing:

cdi-new-bean --named DemoBean --scoped REQUEST

If you type the “cat .” command, you will be able to see the skeleton of your Bean.

cat .
package org.demo.forge.beans;

import javax.enterprise.context.RequestScoped;

@RequestScoped
public class DemoBean {

}

We will add at least one method to the Bean which returns a String:

package org.demo.forge.beans;

import javax.enterprise.context.RequestScoped;

@RequestScoped
public class DemoBean {

    public String greet(String name) {
           return "Hello "+ name;
    }

}

Ok, now we have a minimal piece of code that we can test. Before that, we need to install Arquillian add-on as it’s not available out of the box with Forge:

Configure and install Arquillian

addon-install-from-git --url https://github.com/forge/addon-arquillian.git --coordinate org.arquillian.forge:arquillian-addon

Let’s move to the top of our project:

cd ~~

Now we will create a minimal remote test for the project:

arquillian-setup --test-framework junit --container-adapter wildfly-remote

If we take a look at the arquillian.xml file (available in src/test/resources), you will see that it uses a property of the Chameleon target to hide the actual Server implementation:

<arquillian xmlns="http://jboss.org/schema/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">
  <container default="true" qualifier="arquillian-wildfly-remote">
    <configuration>
      <property name="chameleonTarget">${chameleon.target}</property>
    </configuration>
  </container>
</arquillian>

Within the System Properties of your pom.xml (or using the -D option on the command-line) it’s possible to specify the actual impementation:

<systemPropertyVariables>
                <arquillian.launch>arquillian-wildfly-remote</arquillian.launch>
                <chameleon.target>wildfly:10.1.0.Final:REMOTE</chameleon.target>
</systemPropertyVariables>

Now that Arquillian and Chamaleon are configured, let’s add a test to our project:

arquillian-create-test --targets org.demo.forge.beans.DemoBean

An Arquillian Remote Test is running against a running application server. So let’s assume you have an available WildFly application server up and running.

As it is, the DemoBeanTest class does just a test to verify that the applicaiton has been deployed:

package org.demo.forge.beans;

import org.demo.forge.beans.DemoBean;

import javax.inject.Inject;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;
import static org.hamcrest.core.Is.*;

@RunWith(Arquillian.class)
public class DemoBeanTest {

	@Inject
	private DemoBean demoBean;

	@Deployment
	public static JavaArchive createDeployment() {
		return ShrinkWrap.create(JavaArchive.class).addClass(DemoBean.class)
				.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
	}

	@Test
	public void should_be_deployed() {
		Assert.assertNotNull(demoBean);
	}


}

We will enrich this class a bit to verify that the method “greet” returns the expected greeting to our user:

	@Test
	public void should_greet() {
		assertEquals(demoBean.greet("Frank"),"Hello Frank");
	}

Ok, we are done. We can either build the project from within Forge, using the “build” command, or we can exit the shell and use Maven to build and test it:

$ mvn clean test

At the end, the expected outcome is that both tests complete successfully:

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

To complete this test, you need a remote instance of WildFly available. If you want to use rather a managed test, then you can spin off a WildFly instance on the fly in order to run your test:

Running a Managed Arquillian Test

arquillian-setup --test-framework junit --container-adapter wildfly-managed

In this case, the version of WildFly used for the test is specified in the System Properties which are defined in pom.xml:

<arquillian.launch>arquillian-wildfly-managed</arquillian.launch>
<chameleon.target>wildfly:10.1.0.Final:MANAGED</chameleon.target>

Chameleon will download and extract the target container if no distribution home is configured and target type is either embedded or managed.

Defining your Container Programmatically:

The beauty of Chamaleon is that (as its name suggests) it’s a quite flexible tool. Indeed, you can also specify the ChameleonTarget programmatically, using the @ChameleonTarget annotation, as showed in this piece of code:

@RunWith(ArquillianChameleon.class)

@ChameleonTarget("wildfly:11.0.0.Final:managed")

public class DemoBeanTest {

	@Inject
	private DemoBean demoBean;

}

Compile Arquillian and Chamaleon projects

If you are using JBoss Forge, then the dependencies are handled for you as you add new libraries. However all you need is referencing the umbrella project (Arquillian Universe) and its artifact: arquillian-junit and arquillian-chamaleon:

    <dependency>
      <groupId>org.arquillian.universe</groupId>
      <artifactId>arquillian-junit</artifactId>
      <type>pom</type>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${version.junit}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.arquillian.universe</groupId>
      <artifactId>arquillian-chameleon</artifactId>
      <type>pom</type>
      <scope>test</scope>
    </dependency>

Enjoy the screencast of this tutorial:

{source}
<script src=”https://asciinema.org/a/OQgaWt2cD790fxKrYNrKGqwWE.js” id=”asciicast-OQgaWt2cD790fxKrYNrKGqwWE” async></script>
{/source}

Arquillian Faqs

In this article I’m including a list of common questions related to Arquillian integration testing framework

How to create a WAR deployment with Arquillian

In the following example you can see how to create a War deployment which includes a custom Manifest file (with Dependencies), plus a file into the WEB-INF folder and the Web classes:

@Deployment
public static WebArchive createWarDeployment() {
      WebArchive archive = ShrinkWrap.create(WebArchive.class, "web.war");
         archive
               .setManifest(new StringAsset("Manifest-Version: 1.0\n"
                     + "Dependencies: org.apache.activemq.artemis")
               .addAsWebInfResource(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jms/META-INF/wsdl/HelloWorldService.wsdl"), "classes/META-INF/wsdl/HelloWorldService.wsdl")
               .addClass(org.jboss.test.ws.jaxws.cxf.jms.DeploymentTestServlet.class)
               .addClass(org.jboss.test.ws.jaxws.cxf.jms.HelloWorld.class);
      return archive;
 }

How to create a JAR deployment with Arquillian

In the following example you can check how to create a JAR deployment which includes as well a custom Manifest file:

@Deployment
public static JavaArchive createJarDeployment() {
      JavaArchive archive = ShrinkWrap.create(JavaArchive.class,"ejb.jar");
         archive
               .setManifest(new StringAsset("Manifest-Version: 1.0\n"
                     + "Dependencies: org.apache.activemq.artemis")
               .addClass(org.jboss.test.ws.jaxws.cxf.jms.HelloWorld.class)
               .addClass(org.jboss.test.ws.jaxws.cxf.jms.HelloWorldImpl.class);
      return archive;
}

How to determine the order of deployments with Arquillian

In case you have multiple deployment to be used with Arquillian, you can specify the deployment order with the parameter “order” of the @Deployment annotation:

@Deployment(name="ejb-deployment", order=1)
public static JavaArchive createJarDeployment() {
      JavaArchive archive = ShrinkWrap.create(JavaArchive.class,"ejb.jar");
         archive
               .setManifest(new StringAsset("Manifest-Version: 1.0\n"
                     + "Dependencies: org.apache.activemq.artemis")
               .addClass(org.jboss.test.ws.jaxws.cxf.jms.HelloWorld.class)
               .addClass(org.jboss.test.ws.jaxws.cxf.jms.HelloWorldImpl.class);
      return archive;
}

How does Arquillain find an embedded WildFly ?

You have two options: one is setting the environment variable JBOSS_HOME to path to jBoss installation. Otherwise, a tag property should be added to arquillian.xml inside a container tag:

<arquillian xmlns="http://jboss.org/schema/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">

<container qualifier="jboss" default="true">
    <configuration>
        <property name="jbossHome">/path/to/jboss</property>
    </configuration>
</container>

How do you configure the JVM Parameters of the application server with Arquillian ?

In your arquillian.xml you can add the configuration it tell Wildfly or other application server which xml config to use:

<container qualifier="jboss" default="true">
    <configuration>
        <property name="jbossHome">${jboss.home}</property>
        <property name="serverConfig">standalone-full.xml</property>
       
        <property name="javaVmArguments">-Xmx512m -XX:MaxPermSize=128m -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8787</property 
    </configuration>
</container>

How to perform deploy/undeploy of Arquillian archives programmatically ?

This can be done using the Deployer service which can be in turn injected as @ArquillianResource. See the following example:

@Deployment(name = "App-1", managed = false)
public static WebArchive create() {
  return ShrinkWrap.create(JavaArchive.class);
}

@ArquillianResource
private Deployer deployer;

@Test
public void should_work() {
  deployer.deploy("App-1");
   
  deployer.undeploy("App-1");
}

 

How to use a custom server configuration file for Arquillian

A simple and effective way to use a custom standalone.xml (or its variants) is to pass it via the System Properties contained in javaVmArguments of arquillian.xml.

Here’s an example of it:

<container qualifier="jbossas-managed"  default="true" >

  <configuration>

  <property name="jbossHome">${jbossHome}</property>

  <property name="outputToConsole">true</property>

  <property name="allowConnectingToRunningServer">true</property>

  <property name="javaVmArguments">-Xmx512m -XX:MaxPermSize=256m -Djboss.bind.address=${arquillian.localAddress}
                -Dserver-config=${project.basedir}/src/test/resources/test-standalone.xml
            </property>
  </configuration>
  </container>

 

Arquillian.xml configuration file reference

Here is a table which summarizes the options which you can include into the arquillian.xml configuration file:

Property Default Description
jbossHome $JBOSS_HOME The JBoss configuration to start.
javaHome $JAVA_HOME The Java runtime to use to start the server.
modulePath $module.path The location of the module repository.
javaVmArguments -Xmx512m -XX:MaxPermSize=128m JVM arguments used to start the server.
startupTimeoutInSeconds 30 Time to wait before throwing Exception on server startup.
outputToConsole true Should the server startup console log be piped to the console
serverConfig standalone.xml Which server configuration file to startup with
managementAddress 127.0.0.1 The ip address of the running server instances manage interface
managementPort 9990 The management port for deployment
allowConnectingToRunningServer false If true, if a running AS is found on managementPort, it is used; if false, fails.

And here’s a sample configuration:

<arquillian xmlns="http://jboss.org/schema/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">

	<!-- Force the use of the Servlet 3.0 protocol with all containers, as it 
		is the most mature -->
	<defaultProtocol type="Servlet 3.0" />

	<!-- Example configuration for a remote WildFly instance -->
	<container qualifier="jboss" default="true">
		<!-- By default, arquillian will use the JBOSS_HOME environment variable. 
			Alternatively, the configuration below can be uncommented. -->
		<configuration>
			<property name="jbossHome">/home/jboss/wildfly-10.1.0.Final</property>
			<property name="javaVmArguments">-Xmx512m -XX:MaxPermSize=256m -Djboss.modules.system.pkgs=com.sun.tools.attach,org.jboss.byteman -Xbootclasspath/a:/home/francesco/jdk1.8.0_60/lib/tools.jar</property>
			<property name="allowConnectingToRunningServer">true</property>
		</configuration>
	</container>

</arquillian>

Debugging Arquillian Tests

This short tutorial describes how to debug Arquillian Test Cases using a development environment like Eclipse IDE.

The prerequisite is that you have gone through the basics of Arquillian– you can start from here: Arquillian tutorial

As you already know, Arquillian tests are launched as JUnit test but are executed on the application server environment. Therefore, in order to intercept breakpoints that you have set in Eclipse, you should at first enable remote socket debugging. This can be done by uncommenting the following line from standalone.conf.bat (Windows):

set "JAVA_OPTS=%JAVA_OPTS% -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n"

Unix users, on the other hand will uncomment the following line in standalone.conf:

JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n"

Remote Profile Testing

If you want to debug your Arquillian Tests against a running JBoss AS instance, start by setting the Active Maven Profile as arq-jbossas-remote (or as you called it in your pom.xml).

Now start WildFly / EAP from Eclipse using the Debug Option, as shown by the following picture:

Now set your breakpoints and execute your application as JUnit Test (Run as->JUnit Test). The Debugger perspective will kick in and you will be able to debug your test.

Managed Profile Testing

If you plan to debug your test using a JBoss AS instance managed by Arquillian, you have to set the remote socket debugging options from within your arquillian.xml file as shown by the following example:

<arquillian xmlns="http://jboss.org/schema/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">

    <engine>
        <property name="deploymentExportPath">target/</property>
    </engine>

    <container qualifier="jboss" default="true">
        <protocol type="jmx-as7">
            <property name="executionType">REMOTE</property>
        </protocol>
        <configuration>
            <property name="jbossHome">C:\jboss\jboss-as-7.1.1.Final</property>
            <property name="javaVmArguments">-agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=y</property>
        </configuration>
    </container>

</arquillian>

Now, set the Maven profile to run against a managed Arquillian profile:

Now set your breakpoints and execute your application as JUnit Test (Run as->JUnit Test). That’s all! Happy debugging!

Arquillian tutorial

Arquillian is a platform that simplifies integration testing for Java middleware. It deals with all the plumbing of container management, deployment, and framework initialization so you can focus on the task of writing your tests—real tests. Arquillian minimizes the burden on you—the developer—by covering aspects surrounding test execution; some of these aspects are as follows:

  • Managing the life cycle of the container (start/stop)
  • Bundling the test class with the dependent classes and resources into a deployable archive
  • Enhancing the test class (for example, resolving @Inject, @EJB, and @Resource injections)
  • Deploying the archive to test applications (deploy/undeploy), and capturing results and failures

Enough with introductions, let’s get our hands dirty with a real example!

Do you need a maven archetype to get started quickly with Arquillian ? then build your project with the following one, which will create a project named javaee7arquillian with a Demo application in it:

mvn –batch-mode archetype:generate -DarchetypeGroupId=org.javaee-samples -DarchetypeArtifactId=javaee7-arquillian-archetype -DgroupId=com.mastertheboss -DartifactId=javaee7arquillian

The following is an Arquillian Test Class which is going to test a full Java EE project:

package com.mastertheboss.test;

import java.util.List;
import java.util.UUID;

import javax.inject.Inject;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;

import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.mastertheboss.model.SimpleProperty;
import com.mastertheboss.producer.Producer;
import com.mastertheboss.ejb.ServiceBean;
import com.mastertheboss.repository.RepositoryManager;

@RunWith(Arquillian.class)
public class ServiceTest {
	@Deployment
	public static Archive<?> createTestArchive() {
		return ShrinkWrap.create(WebArchive.class, "test.war").addPackage(ServiceBean.class.getPackage())
				.addPackage(Producer.class.getPackage()).addPackage(SimpleProperty.class.getPackage())
				.addPackage(RepositoryManager.class.getPackage()).addAsResource("META-INF/persistence.xml")
				.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");

	}

	@Inject
	ServiceBean ejb;

	@Inject
	RepositoryManager repo;

	@Test
	public void testRegister() throws Exception {
		String key = UUID.randomUUID().toString();
		String value = UUID.randomUUID().toString();
		SimpleProperty p = new SimpleProperty();
		p.setKey(key);
		p.setValue(value);
		ejb.put(p);

		List<SimpleProperty> list = repo.queryCache();
		assert (list.size() > 0);

		assert (list.get(0).getKey().equals(key));

	}

}

This class is part of a Project which is available onn GitHub at: https://github.com/fmarchioni/mastertheboss/tree/master/javaee/javaee7arquillian . The purpose of this example is to insert a key/value pair using the ServiceBean EJB and then use the RepositoryManager class to verify that data has been actually inserted.
The first thing that you should have noticed is the following annotation that tells JUnit to use Arquillian as the test controller:

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

Arquillian then looks for a static method with the @Deployment annotation; it creates a micro deployment, including all the resources, just as you would when packaging your applications with your favorite tool:

The fluent API provided by the ShrinkWrap project (http://www.jboss.org/shrinkwrap) makes this technique possible using the create method, which accepts the type of deployment unit (WebArchive) as the argument thedeployment name (in our case, we will name it test-demo.war) and all the resources are included in this archive. In our case, instead of including all the single classes, we are using the addPackageutility method that adds all the classes that are contained in a class package.

Building the Arquillian test

Although Arquillian does not depend on a specific build tool, it is commonly used with Maven; it offers dependency management and thus simplifies the task of including the Arquillian libraries in the application since they are distributed in the Central Maven repository.

The first thing that is necessary to include in order to run an Arquillian test is the JUnit dependency that is required to run our unit tests:

<dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <scope>test</scope>
</dependency>

Next, if you want to test enterprise features such as EJB and the Java Transaction API (JTA), you need to include the  org.jboss.arquillian.junit dependency as well:

<dependency>
 <groupId>org.jboss.arquillian.junit</groupId>
 <artifactId>arquillian-junit-container</artifactId>
 <scope>test</scope>
</dependency>

After that, since our Arquillian test uses a protocol to communicate with the server application, we will need to add the org.jboss.arquillian.protocol dependency (named so as it’s compatible with Servlet 2.5/3.0 specifications):

<dependency>
 <groupId>org.jboss.arquillian.protocol</groupId>
 <artifactId>arquillian-protocol-servlet</artifactId>
 <scope>test</scope>
</dependency>

After getting done with the dependencies, we will now include two profiles into our configuration. A profile can basically be used to create different target environments for our goals; in our case, we will create two profiles:
The first profile is named arq-jbossas-managed; it will start a new JBoss AS instance and execute the test, shutting it down when done:

<profile>
   <!-- Run with: mvn clean test -Parq-wildfly-managed -->
   <id>arq-wildfly-managed</id>
   <dependencies>
      <dependency>
         <groupId>org.wildfly.arquillian</groupId>
         <artifactId>wildfly-arquillian-container-managed</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
</profile>

The second profile is named arq-jbossas-remote; it will perform testing against a remote JBoss AS instance:

<profile>
   <!-- Run with: mvn clean test -Parq-wildfly-remote -->
   <id>arq-wildfly-remote</id>
   <dependencies>
      <dependency>
         <groupId>org.wildfly.arquillian</groupId>
         <artifactId>wildfly-arquillian-container-remote</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
</profile>

Running Arquillian Test with a managed container

Arquillian needs to know where WildFly is installed so that it can manage the lifecycle of the container using the startup script. You can configure the JBOSS HOME application into the arquillian.xml file shown as follows:

 
<arquillian xmlns="http://jboss.org/schema/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">
   <defaultProtocol type="Servlet 3.0" />
   <container qualifier="jboss" default="true">
      <configuration>
         <property name="jbossHome">/home/francesco/jboss/wildfly-10.1.0.Final</property>
      </configuration>
   </container>
</arquillian>

Run the test from a terminal windows (or from within your IDE which supports Maven) using:

mvn clean test -Parq-jbossas-managed

Running Arquillian Test with a remote container

You can run the test against a remote JBoss AS installation which by default should be running on localhost and 9999 as management port. You can however override these values by adding to arquillian.xml the following parameters:

<arquillian xmlns="http://jboss.org/schema/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">
   <defaultProtocol type="Servlet 3.0" />
   <container qualifier="jboss" default="true">
      <configuration>
         <property name="managementAddress">myhost</property>
         <property name="managementPort">9990</property>
      </configuration>
   </container>
</arquillian>

In order to run it from a terminal window execute:

mvn clean test -Parq-jbossas-remote

Troubleshooting common Arquillian issues:

My Arquillian tests aren’t being executed!

It’s likely that you are using the surefire-maven-plugin. This plugin does not recognize tests that ends with *IT. You should change it’s name to *Test or use other technique.

I get the following error when launching the test: Caused by: java.lang.IllegalArgumentException: DeployableContainer must be specified

It’s likely that you have no active profile in your pom.xml. Activate the default Arquillian profile as in the following example:

<profile>
   <id>arq-wildfly-managed</id>
   <activation>
      <activeByDefault>true</activeByDefault>
   </activation>
   <dependencies>
      <dependency>
         <groupId>org.wildfly.arquillian</groupId>
         <artifactId>wildfly-arquillian-container-managed</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
</profile>

As an alternative, launch Maven selecting the profile you’re interested in:

mvn clean test -Parq-jbossas-remote

Practical Java EE 7 development on WildFly

This tutorial includes resources from the Practical Java EE 7 development on WildFly If you liked it, consider purchasing a copy of it from Packt Publishing Site