Skip navigation
1 2 Previous Next

Arquillian

27 posts
Dan Allen

Arquillian is on Google+

Posted by Dan Allen Mar 12, 2012

Arquillian is now on Google+.

 

All news about releases, talks, articles and anything else relevant to the project will be shared on the +Arquillian account.

 

GooglePlus 128 Red.png

 

Add Ike to your circles!

According to ohloh, Arquillian has a very large, active development team. Here's a summary of the contributor stats that ohloh curated.

Over the past twelve months, 34 developers contributed new code to Arquillian.

This is one of the largest open-source teams in the world, and is in the top 2% of all project teams on Ohloh.

For this measurement, Ohloh considered only recent changes to the code. Over the entire history of the project, 41 developers have contributed.

Thank you all for making this project so successful and fun! Arquillian has a bright future. Above all other awards and recognitions, it's the number and diversity of contributors that's the most significant. The smartest one amongst us is all of us, working together.

Cheers!

Functional Testing with Arquillian

Arquillian is not only a great tool for testing inside of the container but it greatly reduces the effort for functional testing. In the following article, I'll show you how to easily use it to test a web UI of the application you're building.

 

Getting Started

This article exercises following technologies:

 

The first three are a part of JBoss testing umbrella, the tests themselves are based on Selenium. If you are already familiar with Selenium, you'll find that Arquillian manages not only a container life cycle but it makes your live easier even w.r.t. Selenium life cycle. If Selenium is a new stuff to you, you might find that it is exactly the missing part in your tests.

 

Explaining the concepts of in-container and client testing

 

If you'd ever written an Arquillian based test, you know that it looks almost the same as others tests in the framework you're using. I prefer JUnit here, so let's make an example:

 

@RunWith(Arquillian.class)
public class BasicInContainerTest {
    
    @Deployment
    public static JavaArchive createDeployment() {
        return ShrinkWrap.create(JavaArchive.class)
            .addClass(MyBean.class);
    }
    
    @Inject
    MyBean bean;

    @Test
    public void testBeanInstance() {
        Assert.assertNotNull(bean);
        ..
    }
}
    

Here I've deployed a CDI bean on the server, and in the test I'm injecting the instance and asserting it is working correctly. This means that Arquillian enriches the archive, connects to the server itself, running test method inside of the container. This is actually the default behavior. This way, the JUnit test runner communicates with Arquillian, tests are executed in server JVM and results are pushed back. JUnit runner is actually a client here.

 

The client mode is the second mode of Arquillian testing. This way the tests are executed in the same JVM as the client is running and the testing archive is not enriched. This means you loose the possibility of retrieving objects from server JVM during testing (unless server exposes them otherwise), however Arquillian still controls deployement, undeployment and life cycle of the container.

 

How to activate client mode?

 

This is very easy. You can either mark a deployment non-testable on server, meaning Arquillian will not enrich the archive at all, or you can mark a specified method with an annotation @RunAsClient. Want an example? Here you are:

 

@RunWith(Arquillian.class)
public class BasicClientTest {
    
    @Deployment(testable=false)
    public static WebArchive createDeployment() {
        return ShrinkWrap.create(WebArchive.class)
            .addClasses(MyBean.class)
            .setWebXML("WEB-INF/web.xml");
    }
    
    @Test
    public void testLogin() {
        ...
    }
}    
    

 

Having possibility to annotate a method by @RunAsClient means that Arquillian can run in a mixed mode, giving you the best of both worlds:

 

    ...
    @Deployment
    public static JavaArchive createDeployment() {
        return ShrinkWrap.create(JavaArchive.class)
            .addClass(MyBean.class);
    }
    
    @Inject
    MyBean bean;

    @Test
    public void testBeanInstance() {
        // this is executed in the server JVM
    }
    
    @Test
    @RunAsClient
    public void testFromClient() {
        // this is executed in the client JVM
    }
    ...
    

 

Using Arquillian Drone

 

That was a bit of theory. Let's get back to Arquillian Drone. Arquillian Drone is an extension written in order to manage the life cycle of other objects then servers, to be precise testing browsers.

 

Currently, the list of supported browsers is pretty large, let's mention SeleniumServer, Selenium, WebDriver and Arquillian Ajocado. As well as Arquillian, Arquillian Drone is pretty extensible, so if your favorite testing browser is not supported, you'll find easy to add the support.

 

Arquillian Drone bootstraps the tooling required for testing browsers in order to work (e.g. Selenium Server), than it creates instances of testing browser and properly disposes them after the test is finished. You only have to write the logic of the test, not to meddle with the test environment preparation.

 

Maven configuration

 

This example is built in Maven and tests are configured against JBoss AS 7.0.1 container. The code can be found on github, at https://github.com/kpiwko/blog/tree/master/drone-selenium. Let's go through Maven dependencies:

 

<properties>
    <version.arquillian_core>1.0.0.CR5</version.arquillian_core>
    <version.arquillian_drone>1.0.0.CR2</version.arquillian_drone>
    <version.jbossas_7>7.0.1.Final</version.jbossas_7>
    <version.junit>4.8.2</version.junit>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.jboss.arquillian</groupId>
            <artifactId>arquillian-bom</artifactId>
            <version>${version.arquillian_core}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.extension</groupId>
            <artifactId>arquillian-drone-bom</artifactId>
            <version>${version.arquillian_drone}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>    
    

 

This specifies versions of required tooling, including Selenium. In your dependencies, you'll have to add following artifacts:

<!-- test dependencies -->
<dependency>
    <groupId>org.jboss.arquillian.junit</groupId>
    <artifactId>arquillian-junit-container</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
    <version>${version.junit}</version>
</dependency>

<dependency>
    <groupId>org.jboss.arquillian.extension</groupId>
    <artifactId>arquillian-drone-impl</artifactId>
    <scope>test</scope>
</dependency>

<!-- Support for Selenium in Arquillian Drone -->
<dependency>
    <groupId>org.jboss.arquillian.extension</groupId>
    <artifactId>arquillian-drone-selenium</artifactId>
    <scope>test</scope>
</dependency>

<!-- Support for Selenium Server in Arquillian Drone -->
<dependency>
    <groupId>org.jboss.arquillian.extension</groupId>
    <artifactId>arquillian-drone-selenium-server</artifactId>
    <scope>test</scope>
</dependency>

<!-- Selenium -->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <scope>test</scope>
</dependency>

<!-- Selenium Server -->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-server</artifactId>
    <scope>test</scope>
</dependency>

<!-- Selenium Server dependency, feel free to use different slf4j implementation -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <scope>test</scope>
</dependency>    
    

 

Our example is using ShrinkWrap Maven Resolver to interact with Maven repository from the test itself, so you must include it as well:

 

<!-- Resolution of JAR libraries into WAR archive -->
<dependency>
    <groupId>org.jboss.shrinkwrap.resolver</groupId>
    <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
    <scope>test</scope>
</dependency>
    

 

Finally, you have to specify the dependency on container. JBoss AS 7.0.1 is extremely fast at startup, so let's Arquillian manage its life cycle:

 

<dependency>
    <groupId>org.jboss.as</groupId>
    <artifactId>jboss-as-arquillian-container-managed</artifactId>
    <version>${version.jbossas_7}</version>
    <scope>test</scope>
</dependency>
    

 

Creating a test deployment

 

While running in client test mode, you have to make sure you deploy all the required bits. So, you're deployment method might be a bit more complex but there's nothing to worry about. Here is a commented example:

 

public static final String WEBAPP_SRC = "src/main/webapp";

@Deployment(testable=false)
public static WebArchive createLoginScreenDeployment() {
    MavenDependencyResolver resolver = DependencyResolvers.use(MavenDependencyResolver.class).loadMetadataFromPom("pom.xml");

    return ShrinkWrap.create(WebArchive.class, "cdi-login.war")
            .addClasses(Credentials.class, LoggedIn.class, Login.class, User.class, UsersProducer.class)
            .addAsResource("import.sql")                
            .addAsResource("test-persistence.xml", "META-INF/persistence.xml")
            .addAsWebResource(new File(WEBAPP_SRC, "index.html"))
            .addAsWebResource(new File(WEBAPP_SRC, "home.xhtml"))
            .addAsWebResource(new File(WEBAPP_SRC, "users.xhtml"))
            .addAsWebResource(new File(WEBAPP_SRC, "template.xhtml"))
            .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
            .addAsWebInfResource(new File(WEBAPP_SRC, "WEB-INF/faces-config.xml"))
            .addAsLibraries(resolver.artifact("org.jboss.seam.solder:seam-solder").resolveAsFiles())
            .setWebXML(new File(WEBAPP_SRC, "WEB-INF/web.xml"));
}
    

 

Here I'm enumerating all the files to illustrate the idea. However, ShrinkWrap can add a package, directory and so on, so your method will likely be shorter. I'm creating a WAR archive to be deployed named cdi-login.war. I include all classes, import.sql to populate database with data, test persistence descriptor, all the jsf pages, web and CDI bean descriptor.

 

As I'm using Seam 3 in the example, I'm including all the required libraries as well. Here the resolver is configured using metadata available in the pom.xml file, which defines the project. It collects dependency versions, mirrors, repositories etc. and then you can simply specify groupId and  artifactId to get the Seam Solder jar library. ShrinkWrap Maven Resolver will actually search the local Maven repository and if required (and not configured otherwise) remote repositories as well and fetches Seam Solder including all required transitive dependencies. Then the jar files are packaged in WEB-INF/lib directory.

 

Adding a Selenium browser

 

As you probably noticed, I added Selenium, Selenium Server and corresponding Drone extensions to dependencies in pom.xml file. It's time to used them in the test:

 

@RunWith(Arquillian.class)
public class BasicClientTest {
    ...
    @Drone DefaultSelenium browser;
    ...
    

 

That's it! Specify this as a field in the test and Arquillian Drone extension will create an instance of DefaultSelenium browser before the first client test is run and injects the instance. Here I'm using DefaultSelenium, which requires Selenium Server running. However, because I've included Arquillian Drone Extension for Selenium Server, it will be started as well and the browser connects to it automatically. Do not pollute your tests with unnecessary code, keep them simple!

 

Oh wait, there one more thing. I'm testing web UI but how do I know the URL of deployed application? Arquillian already has a solution:

 

@RunWith(Arquillian.class)
public class BasicClientTest {
    ...
    @ArquillianResource URL deploymentURL;
    ...
    

 

Now even the URL of your deployed archive is injected in the test. You can verify the functionality of the web application:

 

    ...
    private static final String USERNAME_FIELD = "id=loginForm:username";
    private static final String PASSWORD_FIELD = "id=loginForm:password";

    private static final String LOGIN_BUTTON = "id=loginForm:login";
    private static final String LOGGED_IN = "xpath=//li[contains(text(),'Welcome')]";

    private static final String TIMEOUT = "15000";
    
    @Test
    public void testLoginAndLogout() {
        browser.open(deploymentUrl + "home.jsf");

        browser.type(USERNAME_FIELD, "demo");
        browser.type(PASSWORD_FIELD, "demo");
        browser.click(LOGIN_BUTTON);
        browser.waitForPageToLoad(TIMEOUT);

        Assert.assertTrue("User should be logged in!", browser.isElementPresent(LOGGED_IN));
           
    }
    ...
    

 

Easy! You've just tested in the Firefox browser that your application login page works correctly.

 

If you liked the article, stay tuned. There is a lot more in Arquillian Drone to cover, such as configuration of the Arquillian Drone, running different browsers (Firefox, Chromium, IE, etc.); Arquillian Ajocado (Selenium on steroids with an excellent AJAX support included) or WebDriver; multiple browser instances, handling https requests, mobile devices testing and writing support for your own testing browser.

 

Arquillian makes integration testing a breeze. Arquillian Drone adds a great support for functional tests.

Together, they make developing tests fun again.

Even with the first beta still on the horizon, Arquillian has already begun to transform the enterprise testing landscape, making the formerly untestable testable.

The early influence of the Arquillian project is the result of a legion of community members integrating their diverse skills to flatten the barrier to integration testing. The collaboration across projects and across communities is truly inspiring. It's safe to say that not only is the Arquillian invasion on, it's well ahead of its release schedule. And that's awesome. And the growing community is the reason why.

Noble Ike, the Arquillian prince, and the core project team, would like to recognize the community members that have helped shape Arquillian during each release cycle, either through code contributions, participation or advocacy. For donating their time, effort and patience to make Arquillian a better testing framework for the benefit of the community, we award each of them the title Arquillian Noble.

The Arquillian Nobles page on the project site lists the recipients along with the contributions they made. Contributors are awarded for either a specific release, or for general support of the project. The names of the community members crowned so far are listed here (for reference):

  • http://design.jboss.org/arquillian/logo/ui/images/crown/arquillian_ui_crown_256px-glossy.png
  • Pete Muir
  • Cheyenne Weaver
  • Karel Piwko
  • David Allen
  • Andy Gibson
  • Jason Porter
  • Jesper Pedersen
  • Jean Deruelle
  • Thomas Diesler
  • Stale Pedersen
  • Nicklas Karlsson
  • Ken Gullaksen
  • Alejandro Montenegro
  • Adrian Cole
  • Paul Bakker
  • German Escobar
  • Michael Schuetz
  • Adam Warski
  • Markus Eisele
  • Cosmin Martinconi
  • John Ament
  • Stuart Douglas
  • Jordan Ganoff
  • Lincoln Baxter III
  • Mike Brock
Community members may be crowned for multiple releases. Once a contributor becomes a member of the core team, subsequent contributions are not called out (team members are noble by default).

In addition to being listed on the Arquillian Nobles page, we are working to get a crown added to each recipient's JBoss Community profile so that it is globally visible. We'll announce when that's available.

The more container adapters and extensions we create, the more power we put in the hands of the developer, and the better enterprise software will become. Feature transparency FTW!

Thanks to all the Arquillian Nobles, present and future, for making Arquillian awesome and for simplifying testing to child's play!

If you think doing integration testing is significantly slower, complex or just plain harder than unit testing, think again. In this video, Aslak shows how quickly you can go from an empty directory (0mph) to a project that runs a CDI test inside a managed JBoss AS 7 container (60mph) in under a minute using the Arquillian plugin for Seam Forge.

 

 

Arquillian + Seam Forge 0-60 in under a minute from Aslak Knutsen on Vimeo.

 

Notice that the test cold boots JBoss AS 7, deploys the tests and runs it in-container, then undeploys and shuts down the server in < 5 seconds. (It runs even faster when you take away the Maven cycle).

 

A quote by Brian Leathem is suitable for quoting here:

With tools like Arquillian, Shrinkwrap, [and] in-memory databases, [we] are busting through the old barriers of terms like unit and integration tests. Perhaps we need a new term for them: "real tests" or "useful tests" are two possibilities that come to mind.

 

Don't mock. Test for real.

I'm happy to announce that we have moved the Arquillian Reference Guide out of docbook format in the source tree and over to the new JBoss Documentation Confluence instance.

 

https://docs.jboss.org/author/display/ARQ/Home

 

The old DocBook version has been imported and with a few fixes in the imported wiki code it all seems ok.

 

From now on, If you find any errors in the formating or content, you can simply just fix it

Great news! We've drastically cut down the number of dependencies that Maven has to download in order to use the JBoss AS 6 remote container adapter Arquillian. You no longer have to download Hibernate just to connect to a remote or managed (standalone) JBoss AS instance

 

To cut to the chase, replace this dependency:

 

<dependency>
   <groupId>org.jboss.jbossas</groupId>
   <artifactId>jboss-as-client</artifactId>
   <version>6.0.0.Final</version>
   <type>pom</type>
</dependency>

 

with this one:

 

<dependency>
  <groupId>org.jboss.jbossas</groupId>
  <artifactId>jboss-as-profileservice-client</artifactId>
  <version>6.0.0.Final</version>
  <type>pom</type>
</dependency>

 

The number of dependencies drops from 318 to just 28! That should save you a heaps of time. Now, Maven doesn't have download these extra dependenices on the first run, and doesn't have to resolve the graph on subsequent invocations. You also cut out this unresolved pom warning:

 

[WARNING] The POM for ws-commons:policy:jar:1.0 is invalid, transitive dependencies
(if any) will not be available, enable debug logging for more details

 

To make a long story short, the JBoss AS team publishes a stack POM (i.e., BOM) to identify all the dependencies used in JBoss AS. The client POM is a little too well linked and ends up depending on JBoss AS itself somewhere down the line. As you can imagine, this pulls in a lot of transitive dependencies.

 

The profile service client POM is a trimmed down version that grabs only the libraries needed for communicating with a remote (standalone) JBoss AS instance using the DeploymentManager, which is accessed via the ProfileService.

 

Cut the internet a break and update your POM today

After a long wait we can finally give you some good news..

 

*drum roll*

 

Arquillian 1.0.0.Alpha5 has been released!

 

In the beginning of the cycle we came to the conclusion that the old Arquillian core just did not cut it in respect to where we were heading,

so big parts of it has been rewritten...

 

 

Some of the hightlight in this release:

 

  • DeploymentException assertion

 

Verify that a @Deployment throws the expected deployment exception using @ShouldThrowException(Exception.class)

 

   @Deployment @ShouldThrowException(WeldException.class)
   public static WebArchive createTestDeployment() { }

 

  • Multiple deployments

 

Define as many @Deployment methods as you may need. If you need them deployed in order, use @Deployment.order. When dealing with multiple @Deployments you have to specify which deployment context a @Test method should run within by using the @OperateOnDeployment("deploymentName"). The deploymentName is specified using @Deployment.name. With this you can swap between in container testing in one deployment, @RunAsClient in the context of another deployment and back incontainer in the third.

 

   @Deployment(order = 1, name = "dep1")
   public static WebArchive createTestDeployment() { }


   @Deployment(order = 2, name = "dep2")
   public static WebArchive createTestDeployment2() { }


   @Test @OperateOnDeployment("dep1")
   public void callActive1() throws Exception { }


   @Test @OperateOnDeployment("dep2")
   public void callActive1() throws Exception { }

 

  • Multiple containers

 

Deploy multiple deployments to multiple containers in the same test class using @TargetsContainer("containerName") on the @Deployment methods. Combined with @OperateOnDeployment("name") individual @Test methods can now execute in different containers.

 

   @Deployment(name = "dep1") @TargetsContainer("node-1")
   public static WebArchive createTestDeployment() { }


   @Deployment(name = "dep2") @TargetsContainer("node-2")
   public static WebArchive createTestDeployment2() { }


   @Test @OperateOnDeployment("dep1")
   public void callActive1() throws Exception { }


   @Test @OperateOnDeployment("dep2")
   public void callActive1() throws Exception { }

 

  • Configurable protocol

 

Previously the protocol was bound to the container you were running on. The container still has a default, but this can now be overwritten on a pr @Deployment method level by using the annotation @OverProtocol("protocolName").

 

   @Deployment(name = "dep1") @TargetsContainer("node-1") @OverProtocol("Servlet 3.0")
   public static WebArchive createTestDeployment() { }


   @Deployment(name = "dep2") @TargetsContainer("node-2") @OverProtocol("EJB 3.1")
   public static WebArchive createTestDeployment2() { }


   @Test @OperateOnDeployment("dep1") // in container text execution is done over HTTP
   public void callActive1() throws Exception { }


   @Test @OperateOnDeployment("dep2") // in container text execution is done over RMI
   public void callActive1() throws Exception { }

 

  • Descriptor deployment

 

Need to deploy a JMS Queue, or a DataSource? Use the Desciptor deployment. Works the same as a Archive deployment by defining a deployment method with return type Descriptor.

 

   @Deployment
   public static Descriptor createTestDeployment() { }

 

* Arquillian Drone

 

A new extension for Web testing. Integrates Arquillian with Selenium, WebDriver and Arquillian Ajocado.

 

@RunWith(Arquillian.class)
public class AjocadoTestCase
{
   // load ajocado driver
   @Drone
   AjaxSelenium driver;
}

 

 

Some changes:

 

  • @Run(AS_CLIENT) @Run(IN_CONTAINER) has been replaced by @RunAsClient. RunMode is default read from @Deployment.testable, but you can override the runmode for a in container deployment using @RunAsClient on the @Test method.
  • New Configuration XML format
  • GlassFish 3.0 support was _replaced_ with 3.1 support.

 

 

Big thanks to the Arquillian and ShrinkWrap community for helping us with this release!

 

 

A extra goes out to, Karel Piwko for Arquillian Drone, Jason Porter for GlassFish Remote 3.1 container and David R Allen for other random issues

 

[ Arquillian ] | [ JIRA ] | [ SPI Javadoc, API Javadoc ] | [ Reference Guide ] | [ Release Notes ] | [ Maven Artifacts ]

Today sets a new record for Arquillian. Arquillian is being covered in four different presentations, at four different events, in one day: Arquillian D-Day.

 

Event: Red Hat Developer Day

Speaker: Aslak Knutsen

Presentation: Arquillian

 

Event: Javaforum Stockholm

Speaker: Aslak Knutsen

Presentation: Introduction to integration testing in Java EE 6

 

Event: JBUG Belgium

Speaker: Pete Muir

Presentation: Seam 3 / Arquillian

 

Event: oredev 2010

Speaker: Adrian Cole

Presentation: Java provisioning in the cloud

 

These presentations are just the beach landing. The main event is next week, Devoxx 2010, where we'll have some big news.

 

Event: Devoxx 2010

Speaker(s): Aslak Knutsen, Dan Allen & Pete Muir

Presentation: Java enterprise testing made easy with Arquillian (3 hour lab)

 

See ya somewhere!

Dan Allen

We're published!

Posted by Dan Allen Oct 28, 2010

Arquillian may still be in alpha, but it's proven so useful that you can already read about it in publications! In the October 2010 issue of NFJS Magazine, I explain how Arquillian provides a component model for integration testing and why it matters to you. It's fitting that it appears in the issue titled "Control Your Destiny". Here's the abstract for the article:

 

nfjsmag-cover-oct-2010.pngArquillian: A component model for integration testing
by Dan Allen

 

You know you should test. The reasons are prevelant. Tests help you analyze your API, validate the behavior of your business logic, serve as documentation "at the source" for users and maintainers, and so on. The plan is easy to follow, at first, particularly if you're working on a greenfield application.

 

But eventually, you bump into the testing bandgap, the point at which you have to being testing components coupled to other resources, services or layers. (And you really do want to test them, not just mock them). It's at this transition, from unit to integration test, that the ever-important project deadline becomes threatened. Work stops, your browser history floods with search results, the build script multiplies and the code-build-test cycle becomes a code-build...-catch up on tweets-test cycle. Testing becomes a bore (not to mention costly). It's time for a new strategy.

 

If you dial down your social media stream for a few minutes, I'll prove to you that a component model for tests can make an integration test appear as simple as a vanilla unit test. Child's play, really. The secret agent (turned alien invader) is Arquillian, a container-oriented testing framework that enables you to write portable integration tests for enterprise Java applications and beyond. You'll discover how Arquillian's test enrichment, packaging and deployment, in conjunction with container lifecycle management, let you skip the build and test in-container, all without having to leave the comfort of your IDE (or the commandline, if it suits you). With Arquillian in hand, integration testing becomes fun and productive again.

 

Ready to play?

 

I strongly recommend supporting this tech magazine of rare quality. All the authors are NFJS tour speakers and therefore you can expect highly technical, pragmatic and entertaining articles. Visit http://bit.ly/57fCM to subscribe.

 

ejb-3.1-oreilly.pngArquillian is also in print! Walk into most Borders or Barnes and Noble stores and you can find Arquillian used in the examples of Andrew Rubinger's Enterprise JavaBeans 3.1 Sixth Edition, published by O'Reilly.

 

Although the Arquillian story is just getting started, it's already being well told.

arquillian_icon_jpa.pngA while back, 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:

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 (JSR-299) 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).

@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 (src/test/resources-glassfish-embedded/sun-resources.xml) containing the resource definitions, which GlassFish knows how to consume.

<?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 (src/test/resources/arquillian.xml) and configure the Embedded GlassFish container adapter to pick up this file, which it will feed to the asadmin add-resources command.

<?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.).

<?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.

Europe's first JUDCon is starting off in Berlin next week..

 

Pete Muir and I will be kick starting JUDCon with a little WarmUp on the 6. October around 19:00 at the Berlin JUG where we will be presenting Seam 3 / CDI and Arquillian to the local Berliners.

 

On the 7. October at JUDCon, Adrian Cole and I will present "Frictionless integration testing in the cloud" on the Cloud track at 17:30.

 

The 8. October at JUDCon, Michael Schuetz will present "Seam2: Real integration testing with Arquillian" on the JBossAS 6 and 7 Track at 11:00.

 

Join us on for these fun days... and don't forget the HackFest on the 7. from 19:00-02:00!

 

spincode2.png

 

Welcome!

Why deal with complexity? Throw it over the wall! Let ShrinkWrap and Arquillian handle it.

That's the message Andrew Rubinger (ALR) and I took to JavaOne 2010. We lived it too, keeping a constant stream of discussion going about how to reduce the complexity of integration testing. Then, we bundled up all that mental complexity and threw it over the Pacific Coast during our bike ride to the Cliff House and over the Golden Gate Bay Bridge.

alr-and-dan-cover-scaled.jpg

The first morning, I woke up (after several attempts) in a panic because I thought I missed my first JBoss booth mini-session. I even sent an e-mail to the booth coordinator apologizing for running out of steam and not being able to make it. As it turns out, my calendar was playing musical time zones on me and the talk wasn't for another three hours. Saved. In part.

ejb-book-scaled2.jpgAfter two hours of hacking up slides, ALR and I bolted out of the hotel and across the street to the Hilton, where he proceeded to guide me through the labyrinth that housed the partner pavilion. On our way through, we had an accidental encounter with the JavaOne bookstore, so we stopped in to see ALR's EJB 3.1 book in print.

He flipped it over to show me my quote on the back.

ejb-quote-border.png

After our pitstop, we zigzagged our way to the partner pavilion entrance just minutes before my talk would start. The pavilion bouncer barked "Show your passes." I tried to tell her that I hadn't had a chance to pick it up yet and I was presenting in 5 minutes. She didn't want to hear it. She waved her radio like it were a gun, as if she were guarding the entrance to a sheik's lair. "No pass, no access." Round three.

I reentered the labyrinth to find the registration desk. There, I got knighted an official speaker and retraced my steps to the partner pavilion. I got plugged in, wired up and was on camera in under a minute to give my Seam: State of the Union address.

And that's how JavaOne began for me.

As soon as I tore down, ALR was geared up, ready to show booth passersby how to achieve rapid enterprise development by throwing test complexity over the wall. This would be one of two warm-up sessions for our main event at JavaOne.

alr-booth-talk-scaled.jpg

Once I had a chance to step back and look at the booth, I realized there was a surprise waiting for me. Arquillian has a spot on the booth wall.

arquillian-booth-wall-scaled.jpg

It also had a seat front and center in the info stand.

arquillian-info-stand.jpg

Clearly we are making some progress getting our message across. And we're just getting started.

We hung out at the booth the rest of the day, continuing to talk to conference goers about Arquillian and other geek talk. We were excited to here that Arquillian got mentioned in at least one other talk at JavaOne. Reza Rahman and Debu Panda, co-authors of EJB in Action, presented their talk "Testing Java EE 6 Applications: Tools and Techniques" in front of a full house, in which they cited Arquillian as:

An ideal cross-vendor CDI/EJB 3.1 testing tool

You can check out the slides for that talk or browse the demo source code.

I also had a long conversation with Hans and Adam of the Gradle team. I love those guys, and their passion for pragmatic build automation.

That night we decided to have a JBoss dinner at The House of Prime Rib on a recommendation from Jay Balunas, who saw the restaurant featured on the food network. To that, I replied, "You had me at steak." But we had to earn it. Being the athletic, eager type, ALR and I walked 20 blocks, mostly uphill, to the restaurant.

That turned out to be the fasted meal of perfection I've ever had because I still had to make the CDI BOF at the Moscone Center. I walked in 1 minute late to the greeting "So glad you could show up!"

license_asl-on.pngThe CDI BOF went great. I highlighted our commitment to freeing Java standards by putting the CDI TCK and RI (Weld) under the Apache License. I also explained how Arquillian was born out of the TCK and how important it will be to enabling rapid development with Java EE, or at the very least make it easily testable.

I followed David Blevins and Adam Bien to the Thirsty Bear, my only appearance there for the week. (There were very few session in Moscone, so Thirsty Bear was mostly neglected). I got a chance to chat 1-on-1 with Adam Bien, making sure to extend a personal invitation to check out Arquillian. I also enjoyed his many development horror stories.

The story I liked the best was about the architect who wouldn't let him deploy a JSF application that used Facelets without pre-compiling the JSPs. Adam tried to explain that there were no JSPs to pre-compile, but it was wasted breath. So he just added a token JSP and the issue was settled. He cracks me up.

The next day seemed to go quickly. I gave my first JavaOne presentation, CDI, Weld and the future of Seam to a full room. The most important part. I finished on time. Thank goodness.

javaone2010_welcome_poster-scaled3.jpgThat night, we launched our party into the cloud at the JBoss gathering. It was hosted at the historic "Slide" adjacent to Union Square. During Prohibition, the site was called "The Cable Car Theater" and below was a "restaurant" called "Cafe Dans" - but Cafe Dans was not a restaurant. It was a speakeasy that could be accessed only by a savvy few who pushed a secret wall that lead to a playground slide, and a hidden subculture of nightlife. Lot's of community members found the secret door...so it wasn't that secret after all.

What else would you expect from those rebellious JBoss characters? Survey said, "Just like the awesome JBoss parties of old." Glad to see us returning to their roots in an uncertain time.

The next day, ALR and I were back at the booth again, me speaking about Seam and ALR throwing more complexity over the booth wall. Then, we went back to the room to prepare Ike for his JavaOne debut. Throwing complexity over the wall: Rapid development for enterprise Java. Slides, check. Demo, check. This was it.

We got in the room, same routine. After fiddling with displays, workspaces and mics, we looked up to see standing room only attendance. Sweet. It's on. Back and forth ALR and I went chopping down complexity one slide at a time. The demos mostly cooperated. The applause at the end, huge. Lots of interest, lots of excitement. All in a days work

Next up was the JCP awards ceremony. Summary, we didn't win. Moving on.

Everyone was headed over to Treasure Island for the blockbuster concert that was going on there. In the registration rush, I managed to not get issued a ticket. But, thanks to Matthias & friends, I got a "community edition" pass. When we arrived, we learned just how much colorful light a stadium size LED puts out.

big-led-screen-scaled.jpg

A conference, or a festival?

will-i-am-dj-scaled3.jpgWe watched Fergie Pump It and will.i.am spin the old tunes atop a pillar of King Ellison during the Black Eyed Peas performance. We tried to squeeze our way somewhere near the stage. Not a chance. The place was chock full of geeks and plenty of tag-alongs.

In a crowd of nearly 25,000, one guy tapped me on the shoulder and said,

Arquillian looks really cool. I'll have to check it out. You said you'd demo it in a bar. How about at at concert?

What a character! I would have done it too, except I checked my bag.

Our group hung around for Steve Miller, who brought funk, blues, classics and an overall killer performance.

steve-miller-scaled.jpg

We tried to sneak back into downtown for last call, but we were too late. But when I got back to the hotel, ALR greeted me with a bottle of Johnny Walker, Black Label. Hero.

bike-ride-start-scaled3.jpgTech weary, ALR and I decided to skip the last day and instead headed out to bike the Golden Gate Bridge. I was snapping pics with my phone the whole time, despite not having been on a bike in years. I'm crazy like that.

On the recommendation of ALR's friend, we took a detour to Ocean Beach...

ocean-beach-scaled4.jpg

then up to the famous Cliff House for some desperately needed lunch (and for me, breakfast).

cliff-house-alr-dan-scaled.jpg

Despite popular belief, developers do stop to smell the roses occasionally.

roses-scaled.jpg

But we have to be manly too. So we took a peak at an overlook with views of "The Rock" and tried to look really large and in charge for our cover picture.

panoramic-rock-scaled-horizon.jpg

Then it was off to to the bridge, at last. We somehow managed to find the right path, despite vague instructions from the guy at the bike store to "follow the service road to the bridge". Yeah, more like dirt path with random staircases.

golden-gate-serpentine-rock-scaled2.jpggolden-gate-bridge-scaled2.jpg
to-golden-gate-bridge-scaled2.jpgover-bridge-scaled2.jpg

We didn't want to miss the last night out on the town, so we hoped the ferry back from Sausalito and caught the sunset on the way into harbor.

sunset-scaled.jpg

We had one last covert meeting with colleagues in a basement sushi restaurant (aren't those the best kind) about standards and leadership. We then bid farewell. After more than two weeks on the road, I was headed home at last! On the flight home I wrote the lyrics for the Hudson Blues and implemented a Spring container for Arquillian. Crankin' it out.

cliff-house-alr-scaled.jpg

The next time you are writing integration tests for your enterprise Java application, take advice from ALR:

Throw complexity over the wall and lean on Arquillian and ShrinkWrap.

Hudson's down, and it's singin' the blues!

 

To the tune of Everything Is Broken by Bob Dylan.

 

everything-is-broken.png

Hudson blues

 

Broken methods, broken tests
Broken threads, broken specs
Broken asserts, broken source
QA rantin' until they're hoarse
Ain't no use patchin'
Ain't no use mergin'
Every test is broken

 

Broken pages, broken files
Broken urls, broken compiles
Broken markup, broken tags
Hudson's filled with broken builds

 

Broken apps never meant to be tested
Every test is broken

 

Seem like every time you stop and turn around
Another failure report gets emailed out

 

Broken proxies, broken beans
Broken runtimes, broken teams
Broken archives, broken lifecycles
Broken deployments on broken servers

 

Take a deep breath, deal with the crashin'
Every test is broken

 

Everytime you leave and go off someplace
The app falls to pieces in my face

 

Broken hands on broken keyboards
Broken IDEs with broken classes
Broken pipes, broken tools
People bending broken rules
JUnit howling, surefire croakin'
Every test is broken

 

Fix those tests with Arquillian!

The JBoss Developer Webinar Series continues on Aug 18th with a talk by alrubinger and aslak on Enterprise Testing with Arquillian. Don't miss this chance to learn how Arquillian can reduce your enterprise testing tasks to child's play, all without leaving the comfort of your IDE!

 

Registration


https://inquiries.redhat.com/go/redhat/20100818EnterpriseTestingviaArquillian


Webinar Description

 

You know you should test. You know that testing forces you to consider API design. That it proves your implementation, and that it documents for other maintainers its use. That it future-proofs you during refactoring but with too many moving parts, it's hard to fault even the most savvy developer for giving up. Tests have been slow to write, slow to execute, and push back our deadlines.
It doesn't have to be that way anymore.

 

In this session, we'll explore techniques to skip the build and stay within the IDE, reduce boilerplate by harnessing an annotation-driven framework, and hook into some common embeddable EE containers from a plain JavaSE environment.

Replays will be available on the Webinar Series page shortly after the talk. Join us afterwards in the #jbosstesting channel on Freenode IRC for follow-up questions.