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.

Arquillian Chamaleon tutorial wildfly

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>
Found the article helpful? if so please follow us on Socials