The perfect recipe for testing JPA 2, revisited

A while ago, Arun Gupta proposed a recipe for testing JPA 2 (JPQL & Criteria) using Embedded GlassFish in one of his notable Tips of The Day (TOTD #133). Embedded containers such as GlassFish certainly make testing Java EE APIs achievable. But I want to challenge Arun’s conclusion that using Embedded GlassFish programmatically is the perfect recipe for testing.

In this entry, I’ll show that the test can be further simplified. By throwing the complexity of managing the container over the wall, you can focus solely on the task at hand, testing (and experimenting with) JPA 2. Not only does the test get simpler, it also becomes portable, so you are not locked into running it on Embedded GlassFish. Any compliant Java EE container, such as JBoss AS, or even a standalone JPA runtime will do. That’s a lot of flexibility.

The secret ingredient: Arquillian

As in Arun’s TOTD, our test will:

  • persist entities to a database and subsequently query them using JPQL and the JPA 2 Criteria API

But that’s all we’ll worry about. We’ll let Arquillian handle the task of creating the JDBC Connection Pool and JDBC Resource using GlassFish APIs. Even that is behavior specific to the select target container. Other target containers may have parallel operations. That’s of no concern to the test.

Like Arun’s application, ours uses a (video) Game entity with two fields:

  • id – the primary key
  • title – the title of the game

The test persists 3 sample entries to the database and then retrieves them using a JPQL statement and the Criteria API. The test will perform three tasks:

  • store 3 sample entities in the database using the JPA EntityManager
  • query the database using JPQL
  • query the database using Criteria API

The entire source code is available in the Arquillian examples project on github. All you need to see the action is run “mvn test” (and a hint of patience to wait for Maven to download the dependencies).

To get you acclimated, here’s the directory structure of the project.

pom.xml
src
|-- main
|   `-- java
|       `-- com
|           `-- acme
|               `-- jpa
|                   `-- Game.java
`-- test
    |-- java
    |   `-- com
    |       `-- acme
    |           `-- jpa
    |               `-- GamePersistenceTestCase.java
    |-- resources
    |   `-- arquillian.xml
    |-- resources-glassfish-embedded
    |   |-- sun-resources.xml
    |   `-- test-persistence.xml
    `-- resources-jbossas-remote
        |-- jndi.properties
        `-- test-persistence.xml

Game is the JPA entity class and test-persistence.xml provides the definition of our Persistence Unit for the test environment. We won’t touch persistence.xml since that’s the definition for the production environment.

Notice we have resource directories for both Embedded GlassFish and remote JBoss AS. We’ll get into that later.

Here’s the source of the Game entity class, as denoted by the @Entity annotation:

src/main/resources/com/acme/jpa/Game.java
package com.acme.jpa;
 
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
 
@Entity
public class Game implements Serializable {
    private Long id;
    private String title;
 
    public Game() {}
 
    public Game(String title) {
        this.title = title;
    }
 
    @Id @GeneratedValue
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    @NotNull
    @Size(min = 3, max = 50)
    public String getTitle() {
        return title;
    }
 
    public void setTitle(String name) {
        this.title = name;
    }
 
    @Override
    public String toString() {
        return "Game@" + hashCode() + "[id = " + id + "; title = " + title + "]";
    }
}

The primary key is defined using the @Id annotation on the field. Additional columns are derived automatically from bean properties (standard getter/setter convention). You can use the @Column annotation to explicitly set the name of the column. Otherwise, the column name is determined by removing the “get” prefix from the bean property’s read method and lowercasing the first character of the remainder (e.g., getTitle() => title).

We are also using standard Bean Validation annotations to enforce constraints. Here, a title must be provided and it must be between 3 and 50 characters long. That would make a good test.

Let’s create a new JUnit 4 Arquillian test case, GamePersistenceTestCase, and prepare it to test our JPA operations. We’ll leverage CDI to supply us with the resources we need via dependency injection. (We’ll look at an alternative way to accomplish this using a utility EJB in a follow-up post).

src/test/java/com/acme/jpa/test/GamePersistenceTestCase.java
@RunWith(Arquillian.class)
public class GamePersistenceTestCase {
    @Deployment
    public static Archive<?> createDeployment() {
        return ShrinkWrap.create(WebArchive.class, "test.war")
            .addPackage(Game.class.getPackage())
            .addManifestResource("test-persistence.xml", "persistence.xml")
            .addWebResource(EmptyAsset.INSTANCE, "beans.xml");
    }
 
    private static final String[] GAME_TITLES = {
        "Super Mario Brothers",
        "Mario Kart",
        "F-Zero"
    };
    
    @PersistenceContext
    EntityManager em;
    
    @Inject
    UserTransaction utx;
 
    // tests go here
}

Let’s work from top to bottom to understand what’s going on here before we get to the tests.

@RunWith(Arquillian.class)
Tells JUnit to delegate execution of the test to the Arquillian runner. This allows Arquillian to infuse your test with a component model, which consists of container lifecycle management and dependency injection, among other enhancements. Notice that you are not required to extend a base class, so that’s left open to your own design.
@Deployment method
Produces a “micro deployment” archive using the ShrinkWrap API. Arquillian deploys this archive, along with the test case and some additional infrastructure, to the container. The test then executes as a component within this mini application. The contents of this archive are the tests isolated little world.
GAME_TITLES constant
The sample test data
PersistenceContext EntityManager
Injects the persistence context (EntityManager) directly into the test, just as though the test were a managed bean.
@Inject UserTransaction
Injects a JTA transaction directly into the test, a service provided to the managed bean by CDI (JSR-299).
Let’s add a helper method that enters the sample records into the database:
public void insertSampleRecords() throws Exception {
    // clear database
    utx.begin();
    em.joinTransaction();
 
    System.out.println("Clearing the database...");
    em.createQuery("delete from Game").executeUpdate();
 
    // insert records
    System.out.println("Inserting records...");
    for (String title : GAME_TITLES) {
        Game game = new Game(title);
        em.persist(game);
    }
 
    utx.commit();
}

We have to explicitly enlist the EntityManager in the JTA transaction since we are using these two resources independently. Normally enlistment happens automatically within an EJB.

Here’s the test that verifies we can select the sample records using JPQL. We’ll print some logging statements so you can watch what’s going on.

@Test
public void should_be_able_to_select_games_using_jpql() throws Exception {
    insertSampleRecords();
 
    utx.begin();
    em.joinTransaction();
 
    System.out.println("Selecting (using JPQL)...");
    List<Game> games = em.createQuery("select g from Game g order by g.id",
       Game.class).getResultList();
    System.out.println("Found " + games.size() + " games (using JPQL)");
    assertEquals(GAME_TITLES.length, games.size());
 
    for (int i = 0; i < GAME_TITLES.length; i++) {
        assertEquals(GAME_TITLES[i], games.get(i).getTitle());
        System.out.println(games.get(i));
    }
 
    utx.commit();
}

Now for the new stuff! Here’s the same test that uses the Criteria API. Note that this test depends on the JPA 2 annotation processor generating the Game_ metamodel class during the build compilation step.

@Test
public void should_be_able_to_select_games_using_criteria_api() throws Exception {
    insertSampleRecords();
 
    utx.begin();
    em.joinTransaction();
 
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Game> criteria = builder.createQuery(Game.class);
    // FROM clause
    Root<Game> game = criteria.from(Game.class);
    // SELECT clause
    criteria.select(game);
    // ORDER BY clause
    criteria.orderBy(builder.asc(game.get(Game_.id)));
    // No WHERE clause, select all
 
    System.out.println("Selecting (using Criteria)...");
    List<Game> games = em.createQuery(criteria).getResultList();
    System.out.println("Found " + games.size() + " games (using Criteria)");
    assertEquals(GAME_TITLES.length, games.size());
 
    for (int i = 0; i < GAME_TITLES.length; i++) {
        assertEquals(GAME_TITLES[i], games.get(i).getTitle());
        System.out.println(games.get(i));
    }
 
    utx.commit();
}

In order for JPA to work, it needs a Persistence Unit. We define the Persistence Unit in the test-persistence.xml that’s associated with the target container.

ShrinkWrap takes this file from the classpath and puts it into its standard location within the archive.

.addManifestResource("test-persistence.xml", "persistence.xml")

Here’s the entire structure of the archive ShrinkWrap will assemble for this test case (minus the Arquillian infrastructure):

WEB-INF/
|-- beans.xml
|-- classes
|   |-- META-INF
|   |   `-- persistence.xml
|   `-- com
|       `-- acme
|           `-- jpa
|               |-- Game.class
|               |-- GamePersistenceTestCase.class
|               `-- Game_.class
`-- lib
    |-- ...

Let’s look at the Persistence Unit descriptor for Embedded GlassFish:

src/test/resources-glassfish-embedded/test-persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="test">
        <jta-data-source>jdbc/arquillian</jta-data-source>
        <properties>
            <property name="eclipselink.ddl-generation"
                value="drop-and-create-tables"/>
            <property name="eclipselink.logging.level" value="FINE"/>
        </properties>
    </persistence-unit>
</persistence>

We set two vendor-specific properties to activate features of the built-in provider, EclipseLink. The first property tells EclipseLink to generate the database to match the JPA entities. The second property enables logging of SQL statements so we can monitor the activity.

The Persistence Unit is referring to the JTA DataSource named jdbc/arquillian. Where’s that defined? Ah, that’s something the Arquillian container adapter needs to setup. As in Arun’s recipe, we want to use the GlassFish APIs to create a JDBC Connection Pool and associated Resource. But we don’t want to have to code it. We just want to declare it.

First, we create a sun-resources.xml file containing the resource definitions, which GlassFish knows how to consume.

src/test/resources-glassfish-embedded/sun-resources.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC
   -//Sun Microsystems, Inc.//DTD Application Server 9.0 Resource Definitions //EN
   http://www.sun.com/software/appserver/dtds/sun-resources_1_4.dtd>
<resources>
    <jdbc-resource pool-name="ArquillianEmbeddedDerbyPool"
        jndi-name="jdbc/arquillian"/>
    <jdbc-connection-pool name="ArquillianEmbeddedDerbyPool"
        res-type="javax.sql.DataSource"
        datasource-classname="org.apache.derby.jdbc.EmbeddedDataSource"
        is-isolation-level-guaranteed="false">
        <property name="databaseName" value="target/databases/derby"/>
        <property name="createDatabase" value="create"/>
    </jdbc-connection-pool>
</resources>

We’ve now isolated the DataSource definition from the test in the same way we do in the main application. The further benefit is that we can define any resources we might need for our test. Imagine the possibilities.

Now we need to tell Arquillian to use this file. We open up the Arquillian configuration and configure the Embedded GlassFish container adapter to pick up this file, which it will feed to the asadmin add-resources command.

src/test/resources/arquillian.xml
<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns="http://jboss.com/arquillian"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:gfembed="urn:arq:org.jboss.arquillian.container.glassfish.embedded_3">
    <gfembed:container>
        <gfembed:sunResourcesXml>
            src/test/resources-glassfish-embedded/sun-resources.xml
        </gfembed:sunResourcesXml>
    </gfembed:container>
</arquillian>

All that’s left is to setup the Maven build to execute the test. To get this code to actually compile, we have to tell Maven it’s okay to use JDK 6 (it’s stubborn like that).

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.1</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
    </plugins>
</build>

You also need to configure Maven to run the JPA 2 annotation processor, which I describe in another blog entry.

We’re going to separate out the target containers using Maven profiles. All of the profiles will share a common set of dependencies:

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.1</version>
    </dependency>

    <dependency>
        <groupId>org.jboss.arquillian</groupId>
        <artifactId>arquillian-junit</artifactId>
        <version>1.0.0.Alpha4</version>
    </dependency>
</dependencies>

Here’s the profile for Embedded GlassFish. If you don’t want to target multiple containers, you can simply make this part of the top-level configuration.

<profile>
    <id>arq-glassfish-embedded</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <dependencies>
        <dependency>
            <groupId>org.jboss.arquillian.container</groupId>
            <artifactId>arquillian-glassfish-embedded-3</artifactId>
            <version>1.0.0.Alpha4</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.extras</groupId>
            <artifactId>glassfish-embedded-all</artifactId>
            <version>3.0.1</version>
        </dependency>
    </dependencies>
    <build>
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
            </testResource>
            <testResource>
                <directory>src/test/resources-glassfish-embedded</directory>
            </testResource>
        </testResources>
    </build>
</profile>

We are explicitly adding the src/test/resources-glassfish-embedded directory as a test resource directory so that test-persistence.xml is placed into the classpath. Again, if you only intend on using Embedded GlassFish, this file can be moved into the standard Maven location and you can skip this configuration.

When you are done setting everything up, you can run the test with the following command:

$ mvn clean test

The profile for Embedded GlassFish is activated by default. Snippets of the test output is show below.

...
INFO: GlassFish Server Open Source Edition 3.0.1 (java_re-private)
...
Oct 4, 2010 1:01:56 PM org.jboss.arquillian.container.glassfish.embedded_3.GlassFishEmbeddedContainer executeCommand
INFO: add-resources command result (1): JDBC connection pool ArquillianEmbeddedDerbyPool created successfully.
Oct 4, 2010 1:01:56 PM org.jboss.arquillian.container.glassfish.embedded_3.GlassFishEmbeddedContainer executeCommand
INFO: add-resources command result (2): JDBC resource jdbc/arquillian created successfully.
Oct 4, 2010 1:01:56 PM com.sun.enterprise.v3.services.impl.GrizzlyProxy$2$1 onReady
INFO: Grizzly Framework 1.9.18-o started in: 226ms listening on port 8181
...
Oct 4, 2010 1:07:14 PM com.sun.enterprise.web.WebApplication start
INFO: Loading application test at /test
...
Inserting records...
Selecting (using JPQL)...
Found 3 games (using JPQL)
Game@22609264[id = 1; title = Super Mario Brothers]
Game@3655662[id = 2; title = Mario Kart]
Game@20289248[id = 3; title = F-Zero]
Selecting (using Criteria)...
Found 3 games (using Criteria)
Game@25589884[id = 1; title = Super Mario Brothers]
Game@18616220[id = 2; title = Mario Kart]
Game@29940830[id = 3; title = F-Zero]
...
Oct 4, 2010 1:07:16 PM com.sun.enterprise.v3.server.AppServerStartup stop
INFO: Shutdown procedure finished

That’s a real integration test!

What’s more, we can run the exact same test on JBoss AS. We’ll need a different Persistence Unit definition that specifies a JDBC Resource available on JBoss AS and sets some Hibernate configuration settings. (Arquillian doesn’t yet support deploying a DataSource to JBoss AS—though it’s in the pipeline—so for now we use the built-in DataSource, java:/DefaultDS.).

src/test/resources-jbossas-remote/test-persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="test">
        <jta-data-source>java:/DefaultDS</jta-data-source>
        <properties>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
            <property name="hibernate.show_sql" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

Then we need a Maven profile that adds the JBoss AS container adapter and client API libraries and the JBoss AS resources:

<profile>
    <id>arq-jbossas-managed</id>
    <dependencies>
        <dependency>
            <groupId>org.jboss.arquillian.container</groupId>
            <artifactId>arquillian-jbossas-managed-6</artifactId>
            <version>1.0.0.Alpha4</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.jbossas</groupId>
            <artifactId>jboss-as-client</artifactId>
            <version>6.0.0.20100721-M4</version>
            <type>pom</type>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.spec</groupId>
            <artifactId>jboss-javaee-6.0</artifactId>
            <version>1.0.0.Beta7</version>
            <type>pom</type>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.jbossas</groupId>
            <artifactId>jboss-server-manager</artifactId>
            <version>1.0.3.GA</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
            </testResource>
            <testResource>
                <directory>src/test/resources-jbossas-remote</directory>
            </testResource>
        </testResources>
    </build>
</profile>

Now we run the test again using Maven, but this time activate the JBoss AS managed profile. (You need to set the JBOSS_HOME environment variable to point to a JBoss AS installation)

$ mvn clean test -Parq-jbossas-managed

Here’s the kicker. You can run this test into your IDE! Just import the project, open the test case and select “Run As > JUnit Test”. Voila! It works just like any other JUnit test.

Enjoy the perfect recipe for testing JPA!

While it may have seemed like a lot of preparation, recognize that we left no stone unturned. To remind you of the benefits, just look back at how simple the test case is. And remind yourself it’s not bound to any particular Java EE 6 container or JPA 2 implementation.

Stay tuned for other combinations, such as OpenEJB 3.2 Embedded with OpenJPA 2. So far I’ve figured out how to test JPA 1.x applications using OpenEJB 3.1 with OpenJPA, Hibernate and EclipseLink.

Ike, a developer magnet at JUDCon & JBossWorld

Last month, the Arquillian developers got together at Red Hat Summit / JBossWorld 2010, hosted at the Seaport World Trade Center in Boston, to Experience Open Source with our community.

Conference entrance

We asked the community what they wanted to hear about at JUDCon. Survey said…“Arquillian.” So we unleashed Ike and his fleet of testable containers onto JUDCon and JBoss World.

While Arquillian only appeared twice on the official schedule—once at JUDCon, presented by Aslak and myself, and once at JBoss World, presented by ALR—it managed to make an appearance every hour, in one form or another (including bar discussions). Thanks for encouraging him with all the votes!

On the eve of JUDCon, three of the Arquillian ringleaders (Aslak, ALR and Dan) met up at Harvard Square bar for the Boston JBUG to devise a plan to make testing a main focal point of the weeklong conference event:

Arquillian team meetup

Not letting a moment slip by, Arquillian led off the community track at JUDCon early the next morning.

JUDCon 2010 Community Track

Aslak and I wanted to leave a strong impression on the audience. So instead of going on about theory, we prepared a talk on the future of Java EE testing that can be summed up as: demo, demo, demo, demo. With me driving the commands (doing my best to type on a Norwegian keyboard layout), Aslak pointed at the screen and, in a flash, showed how Arquillian can make child’s play out of testing EJBs, JMS, JAX-RS, JPA and even JSF.

Aslak explaining an Arquillian test

While we’ve come a long way with Arquillian, presenting always gets us thinking of other things we can do with it. (Notice Aslak sporting the black Arquillian shirt).

Aslak answering a question

Ike didn’t want to get stuck inside the computer the whole conference, so we printed him on a bunch of shirts and buttons to give away. Our plan was almost foiled because of my absentmindedness, but it was saved when my wife delivered the “bag of goodies” just as the talk was ending. We spread the Arquillian swag around and it scattered off to invade other talks and strike up conversations.

Dan tossing t-shirts

Everytime you turned around, Ike was hitching a ride on someone’s backpack.

Ike pin on backpack

Making his second apparence on the JBoss Community Asylum, this time under the JBoss moniker, Aslak explained how Arquillian makes the task of testing Java EE applications simple and possible. This would be one of many trips to the microphone throughout the week. But this time, he caught some grief from the jokester hosts poking fun at the project name:

Who is Hark William? Is he a country singer or some sort of character from Star Wars?

Aslak set the record straight.

His name is Ike. And he’s from Hollywood. He’s an alien that controls everything inside his little world.

Arquillian icon

If Ike could speak, he would have simply issued the warning:

Don’t mock me.

He must have left quite an impression, because the host immediately credited Arquillian as having “a couple of talks today.” Sure, that’s how we remember it too

Even though the Arquillian team only had one talk at JUDCon, we did have a front row seat in the Code generation world premiere presented by Jesper Pedersen from the IronJacamar Team, showing of their shiny new tool for JCA adaptor source code generation with full Arquillian test support.

So what’s the Arquillian project status? “Alpha3 is coming soon. And more containers.” (Little did they know, three containers would be added later that night).

The podcast had interrupted the JUDCon hackfest. It then proceeded to ultimately disrupt the hackfest when Emmanuel announced at the top of the hour,

Let’s go get some beers.

So all the talk of a hackfest ended up being just that, talk. But wait, not those hard-core Arquillian developers. They’re the only ones that stuck around, pressing on even in the absense of beer.

Arquillian hackfest

“Why?” you ask. Because we were hell-bent on getting the Tomcat and Jetty container integrations working. I did the Jetty integration while Jean Deruelle worked on the one for Tomcat. Lincoln Baxter III looked up from his work laying down the foundation for JBoss Forge.

Developers looking at screen

Once we both got green bars, we finally called it a night and headed out for a round of drinks to celebrate.

Drinks at Whiskey Priest

We took a break the next afternoon to check out the sights and sounds of downtown Boston, which could be seen off in the distance from the conference center.

Boston skyscape

That evening I headed over to the Red Hat Summit kickoff at the pavilion for my booth duty. Ken Gullaksen, one of our top community members, snapped a shot of me sporting our cool Arquillian desktop wallpaper on my Android phone.

Arquillian desktop wallpaper on Android

Fashioning the Arquillian button, I was soon approached by an attendee who asked me if I had any extra. I asked him if he knew what they were for. He replied,

No. But it looks really cool.

Ike, such a developer magnet ~;)

At some point we made our way from the conference center to a bar downtown. Like always, I’m in the bar ranting on about some technology, probably Maven:

Dan ranting at bar

We were up early the next morning for the second Arquillian charge. ALR kicked off the conference by showing how developers can achieve rapid development with Enterprise Java by throwing complexity over the wall and using ShrinkWrap and Arquillian, while at the same time Mark Little, our director, was in the other room explaining how Arquillian fits into our strategy in his JBoss State of the Union address.

Arquillian is central to the evolution of platfoms & relevant for development.

To put it more bluntly, he slipped out,

You need to test the hell out of things.

We agree ~:)

Handling all that complexity for the developer is hard work, though. It really took it’s toll on ALR,

ALR passed out on couch

Arquillian got a mention in the joint RichFaces 4 / Seam Faces talk and the Seam 3: State of Union talk. All the activity had the developers’ interest piqued. When Pete Muir asked during the the JBoss Developer Story BOF what people wanted to hear more about, someone called out,

I want to hear more about the testing tool.

Once again, Aslak was called to the mic to showcase Arquillian. The timing was excellent because Burr Sutter, who is currently focused on improving the developer experience, witnessed first-hand how desperately this tool is needed. Afterwards, I said to him,

It’s like we just showed up with food to a starving country.

And what are they asking for? More.

Until we meet up again, we’ll be hard at work making testing as easy and powerful as possible. That means working closely with our tools guy, Max Andersen (left).

Max, Aslak and ALR

Ike sure had a big week. So at the end of it all, we bought him a drink (at Drink).

Arquillian t-shirt with drink

The Arquillian forums are really heating up! Community participation is what makes the success of Arquillian possible. Keep it up folks!

Conference photos | More conference photos | Arquillian swag

Arquillian 1.0.0 Alpha 1 Released!

I’m happy to announce the first alpha release of Arquillian, an open source (ASL v2) framework for running tests in the container. If you want to read more about Arquillian’s mission and how it fits into our vision for testing at JBoss, read Pete’s companion blog entry, Testing Java EE the JBoss way.

It’s one thing to unit test your code outside of the container, but what happens when you run it inside? Does it still behave the same? How about testing against container managed resources? This is where Arquillian comes into its own.

With Arquillian it’s just as easy to write integration tests as it is to write unit tests. In fact, to minimize the burden on you, Arquillian integrates with familiar testing frameworks, allowing reuse of tools such as the JUnit/TestNG support in your favorite IDE, Maven Surefire, Ant – in fact any tool which supports TestNG or JUnit!

To show you just how simple this is, here’s an example test case setup using JUnit (we’ll get to the actual test next):

@RunWith(org.jboss.arquillian.junit.Arquillian.class)
public class TemperatureConverterTestCase {
 
    @Deployment
    public static JavaArchive createTestArchive() {
        return Archives.create("test.jar", JavaArchive.class)
            .addClasses(TemperatureConverter.class, TemperatureConverterBean.class);
    }
 
}

By using JUnit’s @RunWith annotation, you tell JUnit to use Arquillian as the test controller. Arquillian will then look for a static method marked with the @Deployment annotation, which defines your micro-deployment. In the example above, the micro-deployment contains a session bean interface and implementation, which Arquillian will deploy to the container.

Arquillian hooks into your testing frameworks lifecycle and reacts to events. On the before suite and after suite events the container is started/stopped, while on the before class and after class events your micro-deployment is deployed to/undeployed from the container.

The test case is started in the local JVM. Arquillian then overrides the normal test execution and migrates the test so that it’s executed inside the container. By the time the test framework calls your @Test annotated method, the test is running inside the container, giving us the possibility to work with container managed resources. Here’s the complete test class with JUnit @Test methods.

@RunWith(org.jboss.arquillian.junit.Arquillian.class)
public class TemperatureConverterTestCase {
 
    @Deployment
    public static JavaArchive createTestArchive() {
        return Archives.create("test.jar", JavaArchive.class)
            .addClasses(TemperatureConverter.class, TemperatureConverterBean.class);
    }
 
    @EJB
    TemperatureConverter converter;
 
    @Test
    public void shouldConvertToCelsius() {
        Assert.assertEquals(converter.convertToCelsius(32d), 0d);
        Assert.assertEquals(converter.convertToCelsius(212d), 100d);
    }
 
    @Test
    public void shouldConvertToFarenheit() {
        Assert.assertEquals(converter.convertToFarenheit(0d), 32d);
        Assert.assertEquals(converter.convertToFarenheit(100d), 212d);
    }
}

Note how we can use @EJB to inject the session bean from our deployment into the test case for use in our test method – neat!

The Arquillian TestEnricher SPI supports all the injection annotations from Java EE 6:

  • @EJB
  • @Resource
  • @PersistenceContext
  • @Inject

Since there are no container specific code/configuration in this example test case, it’s portable. That means it can be run in GlassFish, JBoss AS or OpenEJB, or all three! The choice is yours.

I want to learn more, where should I go from here?

You can follow up with some in depth usage scenarios and tests described in these articles:

We also have reference documentation which walks you through the examples from Arquillian, and shows you how to create your own Arquillian test suite. You might also find the Javadoc useful (API, SPI), especially if you plan on adding support for another container. You can also check out the forums and more articles can be found on our community site. If your interested in chatting to us, please drop by #arquillian on irc.freenode.net

So, what’s next?

Some of the things you can expect from Arquillian in the future are:

  • Local run mode — Sometimes, you don’t want to run the test case inside the container itself. A local run mode will be added; a mode where your test controls the deployment but is not deployed as a part of it. This will give you the chance to run a test against, for example, JSF pages or RMI (testing for those nasty Non-Serializable / SessionClosed exceptions).
  • Multiple deployments controlled by same test — Sometimes your micro-deployment is not enough to test on its own and you want to package other components as part of the same deployment. For example, you need to test the interaction between two Web applications.
  • Support for method argument injection — In the first alpha we only support field injection. In alpha 2 we will be extending the TestEnricher SPI to include support for method argument injection:
@Test
public void shouldWithdrawFromAccount(@EJB AccountManager manager)
        throws Exception {
    ...
}
  • Test method interceptors – Another planned enricher SPI is a test method interceptor. With this we can add support for transactions:
@Test
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void shouldWithdrawFromAccount(@EJB AccountManager manager)
        throws Exception {
    ...
}
  • Convention over configuration – The micro-deployments should be as easy as possible to create, so adding support for common conventions should help speed up the test development. For example we can automatically add all classes in the same package as the test class to the deployment
  • Arquillian controlled resources – Sometimes the container requires container specific configuration e.g, java.naming.* parameters needed to create an InitialContext. If the test case has to explicitly deal with this, it places the burden for container portability back on the test case author. Arquillian will provide an extension point to add Arquillian created/managed resources:
// auto creation of InitialContext based on running container, remote or local.
@ArquillianResource
InitialContext context;
// auto creation of URL to a deployed Servlet, including http port/ip etc.
@ArquillianResource(MyServlet.class)
URL myServletURL;
// the bundle context of a deployed osgi bundle
@ArquillianResource
BundleContext context;
  • Support for more containers – We will plan to support more containers! Currently we have planned: GlassFish 3 (as a remote container), Jetty, Tomcat, Resin, Felix OSGI. (Hey Spring guys, you’re welcome to join in too!)
  • Third party integrations – In the spirit of ease of development, we integrate with existing test frameworks as much as possible, but we are always keen to learn of new frameworks we can integrate with. We already plan to support Selenium for example.
  • Support for other build tools – Arquillian Alpha1 comes with Maven support. In upcoming releases, we will distribute builds targeted toward other build tools like Ant and Gradle (that shout out is for our resident Gradle expert, Jason Porter).
  • A project page, logo and artwork – All good things must look good. That’s why the JBoss.org design team is hard at work putting together artwork for the Arquillian project page. Stay tuned!

Where can I see Arquillian in use?

Arquillian is a new framework, but it’s going to be put right to work as the workhorse to test all the Seam 3 modules. It will also be our recommended solution for testing your Seam application. (We’d love to see the community try it out for testing Seam 2 applications). We’ll also replace the current core of the JSR-299 CDI TCK with Arquillian, likely for the 1.1 version of the TCK. (To provide a little history, Arquillian originated from the JBoss Test Harness that was developed by Pete Muir as the foundation of the CDI TCK).

If you have any thoughts on these ideas, or would like to suggest some new avenues we should explore, please contact us on the Arquillian Dev forum.

And, what’s open source with out the community?!

A big thanks to the Arquillian and ShrinkWrap community for helping out on this release by being early adopters, joining in on community meetings, general discussions and writing blogs, articles and patches. In alphabetical order: Dan Allen, Steven Boscarine, German Escobar, Jordan Ganoff, Ken Gullaksen, Pete Muir, Jason Porter and Andrew Lee Rubinger. You guys rock!

[ Issues | Javadoc: API, SPI | Reference Guide | Release Notes | Maven artifacts ]

This post was syndicated from in.relation.to. See the original blog entry to view older comments.

Testing Java EE the JBoss way

Recently, we’ve been working hard on a solution to improve the testability of Java EE, and particularly JBoss AS. I’m pleased to say that a critical piece of puzzle, Arqullian, is now available. Congratulations to Aslak and the Arquillian team for releasing the first alpha of Arquillian! You can read more about Arquillian’s mission, and our plans for Java EE testing below; alternatively, there are some quick links at the bottom if you want to dive right in.

The mission of the Arquillian project is to provide a simple test harness that developers can use to produce a broad range of integration tests for their Java applications (most likely enterprise applications). A test case may be executed within the container, deployed alongside the code under test, or by coordinating with the container, acting as a client to the deployed code.

Arquillian defines two styles of container, remote and embedded. A remote container resides in a separate JVM from the test runner. Its lifecycle may be managed by Arquillian, or Arquillian may bind to a container that is already started. An embedded container resides in the same JVM and is mostly likely managed by Arquillian. Containers can be further classified by their capabilities. Examples include a fully compliant Java EE application server (e.g., GlassFish, JBoss AS, Embedded GlassFish), a Servlet container (e.g., Tomcat, Jetty) and a bean container (e.g., Weld SE). Arquillian ensures that the container used for testing is pluggable, so the developer is not locked into a proprietary testing environment.

Arquillian seeks to minimize the burden on the developer to carry out integration testing by handling all aspects of test execution, including:

  • managing the lifecycle of the container (start/stop),
  • bundling the test class with dependent classes and resources into a deployable archive,
  • enhancing the test class (e.g., resolving @Inject, @EJB and @Resource injections),
  • deploying the archive to test (deploy/undeploy) and
  • capturing results and failures.

To avoid introducing unnecessary complexity into the developer’s build environment, Arquillian integrates transparently with familiar testing frameworks (e.g., JUnit 4, TestNG 5), allowing tests to be launched using existing IDE, Ant and Maven test plugins without any add-ons.

The Arquillian Mission Statement

The first alpha release of Arquillian gives us support for JBoss AS (remote deployments), GlassFish (embedded deployments), Weld SE (embedded deployments) and OpenEJB (embedded deployments). You can also inject beans and component (using @Resource or @Inject) into test cases.

We’ll be adding supported containers in future releases – if you want to see your favorite container on the list, join our community and we can show you how to add support for it. We also plan to add more convention over configuration, meaning you’ll only need to specify a single deployment and reuse it in all your test cases. Aslak has written more about future ideas in a follow-up blog entry announcing the 1.0.0 Alpha 1 release. In that entry he also provides some examples of how to use Arquillian.

We’re strong believers in writing tests, and writing tests which actually test your business logic in the environment it will finally run in, rather than introducing mocked out objects (which may behave differently). While unit testing is important to ensure the correctness of your logic, it does not ensure the correctness of two objects which interact with each other.

With the help of the ShrinkWrap project, Arquillian gives you the ability to create micro-deployments around your tests. Micro-deployments are contained sub-sections of your application logic. This gives you the ability to do lower level integration testing on a lower level then normal integration. It is up to you at what level you want to test!

We also know you need a convenient way to run your test quickly, and that is why we are getting JBoss Embedded AS in shape. Embedded AS offers the potential to bootstrap JBoss AS inside the same JVM when you run your test, making it super easy to debug the test. Unfortunately, Embedded AS support didn’t make this release (we made a decision to release what we have now, rather than delay), but we will push this out to you as soon as it’s ready.

Testing your components and services gets you a long way, but you’ll nearly always want to test your presentation tier as well. And that’s where frameworks like JSFUnit and Selenium come in – they allow you to exercise the work flows your user will use. Support for both these frameworks is planned, as well as for Mock JSF Objects.

If you like what you’ve heard so far, but are worried that Arquillian requires build script wizardry to use, let us surprise you again! Being able to run any of these tests from within the IDE is a key goal of Arquillian — and the key to a rapid development cycle. Arquillian requires no build wizardry! So check out the documentation and give it a try today!

[ Issues | Javadoc: API, SPI | Reference Guide | Release Notes ]

This post was syndicated from in.relation.to. See the original blog entry to view older comments.