TL;DR
This guide gets you acquainted with the Arquillian plugin for JBoss Forge. After reading this guide, you’ll be able to:
- Install the Arquillian plugin into your Forge installation
- Use the plugin to add the Arquillian infrastructure to a Maven-based Java project
- Generate a component and corresponding Arquillian test
- Execute the Arquillian test on multiple containers without manual configuration
You’ll be performing many of the same steps described in the Getting Started guide, only you’ll be letting Forge handle the dirty work for you. We’ve designed this guide to be a fast read to get you started quicker than ever before!
Assumptions
This guide assumes you have JBoss Forge setup. Installing Forge is a relatively short process. Refer to the Getting Started guide or the official Forge documentation for download and installation instructions. You’ll also need JDK 1.8 or higher installed on your machine.
Create a Project
Before we can get started with Arquillian, we first need a project. If you have not created one yet, use the following Forge commands to generate a basic Java EE 7 project that includes CDI.
$ project-new --named arquillian-tutorial --stack JAVA_EE_7
***SUCCESS*** Project named 'arquillian-tutorial' has been created.
***SUCCESS*** Stack 'Java EE 7' installed in project
Your new project is now created! Next, we need to create some code to test. Let’s use Forge to create a new CDI bean.
$ cdi-new-bean --named MySimpleBean --scoped DEPENDENT
***SUCCESS*** CDI has been installed.
***SUCCESS*** CDI Bean org.arquillian.tutorial.beans.MySimpleBean was created
The project now has a component. Switch back to the project root and get ready to test it!
$ cd ~~
Setup Arquillian
Setting up Arquillian is easy, as you might have seen in the Getting Started guide. However, there is a lot of copy/paste work required to setup a new Arquillian container adapter in the pom.xml. Forge can do that for you with a single command!
First you will need to install JBoss Forge Arquillian Addon. Go to Forge CLI, run following command.
$ addon-install-from-git --url https://github.com/forge/arquillian-addon.git
***INFO*** Installing Addon from Git [1/4] ...
***INFO*** Installing Addon from Git:Cloning repository in /tmp/tmpdir4655938727449657226 [1/4] ...
***INFO*** Installing Addon from Git:Installing project into local repository [2/4] ...
***INFO*** Installing Addon from Git:Removing previous addon installation (org.arquillian.forge:arquillian-addon,1.0.0-SNAPSHOT) [3/4] ...
***INFO*** Installing Addon from Git:Installing addon (org.arquillian.forge:arquillian-addon,1.0.0-SNAPSHOT) [4/4] ...
***SUCCESS*** Addon(s) [org.arquillian.forge:arquillian-addon,1.0.0-SNAPSHOT] installed successfully.
The Addon is ready to use. Now we need to set up Arquillian, Container Adapter, Test Framework. We’ll configure Arquillian to use wildfly in Managed mode, JUnit as a test framework.
$ arquillian-setup --test-framework junit --container-adapter wildfly-managed
***SUCCESS*** Arquillian setup complete
***SUCCESS*** Installed Arquillian Universe 1.1.13.0
***SUCCESS*** Installed junit
***SUCCESS*** Installed Arquillian Container WildFly Managed
***SUCCESS*** Installed Arquillian Container WildFly Managed dependencies
In above command Forge is using latest version of Arquillian BOM, Junit & WildFly.
Try to use latest version of each dependency. If you don’t want to use latest version of arquillian bom, test framework, container adapter, you can easily change it by using --arquillian-version
, --test-framework-version
& --container-adapter-version
options.
Forge will prompt you which version of JUnit, Arquillian and WildFly to use.
Forge will set up container for you using Chameleon if selected container & version is supported by chameleon, otherwise forge will set it up using normal way of arquillian. You can look for which containers & versions are supported by chameleon here
In either case, If you want start WildFly with some different configuration properties like jbossHome
, javaVmArguments
, managementPort
& many more.The preferred way is to set the properties explicitly using the propertyName
(e.g.managementPort
) container configuration property in the arquillian.xml file. Forge can help us out with that:
$ arquillian-container-configuration --container arquillian-wildfly-managed --container-option
javaHome jbossHome managementPort outputToConsole startupTimeoutInSeconds
javaVmArguments managementAddress modulePath serverConfig
Using above command, you can override any default property of your container configuration by setting it’s appropriate value in arquilliain.xml using forge.
Note: In this example we are not going to override any default configuration property.
Here’s the resulting arquillian.xml file (formatted for clarity):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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-managed">
<configuration>
<property name="chameleonTarget">${chameleon.target}</property>
</configuration>
</container>
</arquillian>
That’s it! Arquillian is configured and ready to run tests inside JBoss AS 7.
Write a Test
Now let’s write a test. Once again, Forge can help you get started quickly.
$ arquillian-create-test --targets org.arquillian.tutorial.beans.MySimpleBean
***SUCCESS*** Created test class org.arquillian.tutorial.beans.MySimpleBeanTest
package org.arquillian.tutorial.beans;
import org.arquillian.tutorial.beans.MySimpleBean;
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 MySimpleBeanTest {
@Inject private MySimpleBean mySimpleBean;
@Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addClass(MySimpleBean.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }
@Test public void should_be_deployed() { Assert.assertNotNull(mySimpleBean); } }
As you can see, the test injects the class under test (i.e., MySimpleBean
) using CDI, so this will immediately prove if the test really runs in a container.
You can run the test from your IDE, from Maven (outside of Forge) or from Forge itself. Let’s stick with Forge.
$ build test
... ------------------------------------------------------- T E S T S ------------------------------------------------------- Running org.arquillian.example.MySimpleBeanTest ... Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
Congratulations! You’ve earned your first green bar with Arquillian and JBoss Forge!
Now let’s try to test some JPA code.
Test Persistence
Before we can start writing tests that use the Java Persistence API (JPA), we need to configure JPA. We will then create an Entity and a corresponding Data Access Object. These are the classes we will test.
$ jpa-setup --jpa-provider Hibernate 4.x
***SUCCESS*** Persistence (JPA) is installed.
Now create our entity.
$ jpa-new-entity --named Language --target-package org.arquillian.tutorial.domain
***SUCCESS*** JPA Entity org.arquillian.tutorial.domain.Language was created
Then add some fields to our entity.
$ jpa-new-field --named name
***SUCCESS*** Field name created
If you open the Language
class, you’ll see a typical JPA entity structure.
Now we need a Data Access Object (DAO) to manage this entity. Copy this dao class into your project.
package org.arquillian.tutorial.repository;
import org.arquillian.tutorial.domain.Language; import javax.annotation.PostConstruct; import javax.ejb.Singleton; import javax.ejb.Startup; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import java.util.List;
@Singleton @Startup public class LanguageDao { @PersistenceContext EntityManager em;
public List<Language> listLanguages() { return em.createQuery("select l from Language l").getResultList(); }
@PostConstruct public void insertTestData() { Language java = new Language(); java.setName("Java"); em.persist(java);
Language ruby = new Language(); ruby.setName("Ruby"); em.persist(ruby);
Language groovy = new Language(); groovy.setName("Groovy"); em.persist(groovy); } }
It’s now time to create our test class. This part should look familiar from the first half of this tutorial, except this time we instruct the create-test
command to prepare the test for testing JPA.
$ arquillian-create-test --targets org.arquillian.tutorial.repository.LanguageDao --enable-jpa
***SUCCESS*** Created test class org.arquillian.tutorial.repository.LanguageDaoTest
This again creates a new test, but also adds your persistence.xml to the deployment. Here’s the test it generated:
package org.arquillian.tutorial.repository;
import org.arquillian.tutorial.repository.LanguageDao;
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 LanguageDaoTest {
@Inject private LanguageDao languageDao;
@Deployment public static JavaArchive createDeployment() { return ShrinkWrap .create(JavaArchive.class) .addClass(LanguageDao.class) .addAsManifestResource("META-INF/persistence.xml", "persistence.xml") .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }
@Test public void should_be_deployed() { Assert.assertNotNull(languageDao); } }
Open the test in your IDE and add the Language
entity to the deployment. Add the proper import, then change this line:
.addClass(LanguageDao.class)
…to this one:
.addClasses(Language.class, LanguageDao.class)
After adding `Language.class`, you have to import Language class to compile LanguageDaoTest.
Add following import statement in `LanguageDaoTest.java`
bc(prettify)..
import org.arquillian.tutorial.domain.Language;
Now write a new test method to assert the behavior of listLanguages()
.
@Test
public void testListLanguages() {
Assert.assertEquals(3, languageDao.listLanguages().size());
}
Now run the tests.
$ build test
Congratulations! Another green bar with Arquillian!
Add More Container Adapters
Adding more container adapters is as easy as executing the setup command again. For example, let’s add a Glassfish remote adapter.
$ arquillian-container-setup --container-adapter glassfish-remote
Simply switch between containers by switching the Maven profile. For example in Forge:
$ build test --profile arquillian-glassfish-remote
Some additional setup is required to get this test to work on a standalone GlassFish instance. Call it homework ~:)
Share the Knowledge
Find this guide useful?
There’s a lot more about Arquillian to cover. If you’re ready to learn more, check out the other available guides.
Feedback
Find a bug in the guide? Something missing? You can fix it by forking this website, making the correction and sending a pull request. If you’re just plain stuck, feel free to ask a question in the user discussion forum.
Recent Changelog
- Sep 21, 2017: Fix(scripts) timeout for waiting for timestamp available on pages is by Matous Jobanek