09 May 2010

jeeunit: In-Container Integration Testing for Java EE 6

Recently, I've started working with Java EE 6 in general and Glassfish v3 in particular. Some software engineering best practices do not really depend on the framework or even the language you work with, so I was looking for a convenient way of doing automatic integration tests.

I've been in the habit of using JUnit not just for unit tests, but also for integration or system tests, so this was a natural starting point.

Traditionally, Java EE containers were heavy-weight machinery so that people preferred writing their tests to run out-of-container, paying the price of emulating or mocking some of the container functionality.

Maybe I've been looking in the wrong places, but most of the out-of-container testing approaches like ejb3unit seem to carry more baggage than the container itself, at least when it comes to working with Glassfish v3.

Anyway, as I could not find a ready-to-go solution, I wrote a little JUnit extension called jeeunit together with an example project showing how to set things up with Glassfish v3 and Maven.

The jeeunit project is available from Google Code under an Apache License.

6 comments:

Gregor said...

Have you looked at Arquillian?
It is a flexible framework for EE testing, both in-container or alongside the deployed application:

http://jboss.org/arquillian

“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.”

There are integrations for Glassfish, JBoss, Tomcat, Jetty, OSGi and more (through an SPI).

Just heard about it on JAX 2010 and trying it out on my local JBoss.

Harald Wellmann said...

Yes, I had a look at the manual and was deterred by the fact that there is no release yet but only an alpha snapshot, and it's hard to tell whether or not it will pull a whole bunch of JBoss libs as dependencies.

For now, my tiny jeeunit lib does its job.

But I'll definitely keep an eye on Arquillian.

Aslak said...

Arquillian will keep its dependency set as minimal as possible to be compatible with as many containers and technologies as possible(currently only dependent on ShrinkWrap which is used for packaging). The goal of the project is to make a extendable platform for container testing; that being EE, Cloud, Bean Managers, Remote environments or anything else that can provide resources/services etc. By extendable meaning it can adopt to new technologies and integrate with existing tools and frameworks.

Arquillian is released in Alpha4. Alpha4 is still a release, not a SNAPSHOT pr definition. :)

Arquillian is currently used as test framework for: Seam3, Weld(and GlassFish team for Weld integration), JBoss AS 7, JBoss OSGi

Got some interesting initiatives like OpenTck.org coming along.

Coming in the next version you will see a lot more advanced features like:
- multiple containers
- multiple deployments
- multiple protocols

Which means you can from the same TestClass deploy multiple deployments against multiple containers(embedded or remote) using different protocols. Having @Test 1 execute against container 1 using HTTP and @Test 2 execute against container 2 using EJB as communication.

Here is a example of a Infinispan test case running on 3 embedded tomcat nodes testing a cluster: http://arquillian.pastebin.com/nKcsQtyu

Would love it if we could join efforts and work together to make the world a better place.. :)

Harald Wellmann said...

I had a look at Arquillian 1.0.0.Alpha4 recently, but I didn't manage to run the jeeunit Example tests under Arquillian and got stuck in mysterious exceptions.

So for the time being, I prefer my small solution jeeunit which solves my problem to the big solution Arquillian which only creates new problems.

jeeunit is even easier to use with some new features I added last week, see here.

The main differences between jeeunit and Arquillian:

* jeeunit automatically builds a WAR from your classpath contents. You do not have to deal with assembly and deployment à la ShrinkWrap (actually, I don't think it's a good idea to mimick parts of the build process in your test code).

* jeeunit supports multiple test classes within the same run, unlike Arquillian where you currently (1.0.0.Alpha4) need to repeat the deployment code in every test class.

* jeeunit focuses on Glassfish. Now that JBoss 6.0.0 is released, I was planning to have a go at that, only to find that there is still no documentation for the 6.0.0, so I'll wait until at least a Getting Started Guide is available, I just don't have the time to learn JBoss by trial and error.

Aslak said...

What mysterious exceptions?
(Trying GlassFish Embedded 3.1? They changed their APIs drastically since the Arquillian Alpha4 release starting from 3.0-b09 ->, the last known working v. A updated 3.1 Embedded container is coming in next release. https://issues.jboss.org/browse/ARQ-346)


Building a WAR from your whole classpath is a easy extension to provide for Arquillian(Arquillian has a very rich SPI). The reason why we don't do that default is because your compile classpath provided by the build system is not the same as your runtime classpath and will in some cases cause your runtime to fail.
Another reason is, the archive declaration gives you a classpath isolation, a focus for your testcase. This testcase will test these specific things. With out that isolation, any deployment failure will crash your whole test suite, and the failure may be completely unrelated to the running testcase.


Support for 'suites' are planned.

If you want JBoss support, you can look at the Arquillian JBoss AS 6 Embedded Container for how the API works: https://github.com/arquillian/arquillian/blob/master/containers/jbossas-embedded-6/src/main/java/org/jboss/arquillian/container/jbossas/embedded_6/JBossASEmbeddedContainer.java


-aslak-

Harald Wellmann said...

Aslak, I see your point, but I don't agree...

I did some work with Spring lately, and though I'm not really a fan of it, the Spring Test Context and the SpringJUnit4Runner showed how easy integration testing can (and should) be.

With this background and the new Embedded Glassfish API, I came up with the solution implemented in jeeunit 0.6.0, automatically building an on-the-fly WAR from everything visible on the classpath.

Of course this may not be what you want in all cases, but it currently is all I need for testing my persistence and service layer components.

When you have the case that grabbing everything from your classpath will break your test, this could be a sign that your project setup is not properly modularized.

Using Maven, Eclipse and m2eclipse, and carefully configuring the compile and test scopes, I usually get just what I need for my test deployment to work automatically.

ShinkWrap is actually one of the reasons why Arquillian does not appeal to me. I don't see the point in burdening my test code with things that Maven can do better or that can be done automatically.

What about Convention over Configuration? I think Arquillian might default to building a grab-all-you-can WAR from the classpath, giving the user a choice to use ShrinkWrap to override the default, without forcing him to do so.

On a more specific level, I simply don't see how to deal with classpath folders with ShrinkWrap, and the Javadoc is not very helpful.

Embedded Glassfish has a rather handy API method ScatteredArchive.addClassPath() which does just what I need, both for class folders and JARs.

I've tried using Archive.addDirectory() which just appears to create an empty folder, then I found the ExplodedImporter, which lets me import a directory tree, but only to the root of the archive, and not to WEB-INF/classes - is there a way to set the target location within the archive?

Thanks for the JBoss AS 6 Embedded Container example - that should be enough to get me started!