Help

It would be great if I could use the TestNG plugin for IntelliJ but I'm still on version 4.5 and its only available for IDEA 5. Tried to switch a few times but the XML editor just doesn't work anymore and throws exceptions faster than I can click. I want the XML editor of IDEA 3.x back, it just worked and didn't have the goofy indentation routines of 4.x...

Still, after using TestNG only for a a day or two, I think that its so much better than JUnit that I wonder why I didn't try earlier. I guess I should have listened to Gavin who was raving about how easy it was to get the Seam tests up and running. It actually has all the things I've been missing with JUnit.

So I got my first TestNG setup running nicely for CaveatEmptor. By the way, I've uploaded a new alpha release that includes all the stuff I'm going to talk about here (and quite a few other new things). For those of you interested in the progress of the /Hibernate in Action/ second edition: I've completed 95% of all mapping examples, which I think (and hope) was the most time consuming part. I'm now updating the chapters about sessions, transactions, caching, etc., so finishing the manuscript this year is possible, I guess.

Back to TestNG and how I used it to test EJBs. One of the nice things about TestNG is how easy it is to configure runtime infrastructure you need for your tests. First I wrote a class that boots the JBoss EJB 3.0 container. TestNG will run the startup() and shutdown() methods for a suite of tests:

public class EJB3Container {

    private static InitialContext initialContext;
    private EJB3StandaloneDeployer deployer;

    @Configuration(beforeSuite = true)
    public void startup() {
        try {

            // Boot the JBoss Microcontainer with EJB3 settings, loads ejb3-interceptors-aop.xml
            EJB3StandaloneBootstrap.boot(null);

            // Deploy CaveatEmptor beans (datasource, mostly)
            EJB3StandaloneBootstrap.deployXmlResource("caveatemptor-beans.xml");

            // Add all EJBs found in the archive that has this file
            deployer = new EJB3StandaloneDeployer();
            deployer.getArchivesByResource().add("META-INF/persistence.xml");

            // Deploy everything we got
            deployer.create();
            deployer.start();

            // Create InitialContext from jndi.properties
            initialContext = new InitialContext();

        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    @Configuration(afterSuite = true)
    public void shutdown() {
        try {
            deployer.stop();
            deployer.destroy();
            EJB3StandaloneBootstrap.shutdown();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    public static Object lookup(String beanName) {
        try {
            return initialContext.lookup(beanName);
        } catch (NamingException ex) {
            throw new RuntimeException("Couldn't lookup: " + beanName, ex);
        }
    }

}

First thing on startup, I boot the JBoss Microcontainer, which is actually the kernel of the future JBoss AS 5.x. Because I'm using the EJB3StandaloneBootstrap it will automatically search for the configuration files for the EJB 3.0 container. You need those and the required libraries in your classpath. If you want to try this download CaveatEmptor and copy the libraries and configuration.

Next I'm deploying some beans from caveatemptor-beans.xml, right now this includes just a single datasource for integration testing. It is configured to use JTA and bound to JNDI, services provided by the microcontainer. You can set up and wire other stateless POJO services there if you have to.

Finally I'm deploying all EJBs for my tests. The EJB3StandaloneDeployer supports many different deployment strategies and I decided to use search the classpath and deploy the JAR that contains this file. For EJB 3.0 persistence, which is what I'm primarily testing in CaveatEmptor, I have to have a META-INF/persistence.xml configuration anyway for an EntityManagerFactory. I actually have to figure out how to deploy an exploded archive with a single command and auto-discovery of EJBs...

Now if I write a test class I will need a starting point, I need to get a handle on one of my EJBs. I can look them up in JNDI - that's what the static lookup() method is good for - or I could wire them into my test classes with the microcontainer. I decided to use a lookup:

public class CategoryItem {

    @Test(groups = {"integration.database"})
    public void saveCategory() {

        CategoryDAO catDAO = (CategoryDAO)EJB3Container.lookup(CategoryDAO.class.getName());
        Category newCat = new Category("Foo");
        catDAO.makePersistent(newCat);

    }
}

Here I'm testing a data access object. Well, I'm not actually testing much as I don't assert any state after saving. I still have to port all my JUnit tests over but my first goal was to have the infrastructure ready.

The CategoryDAO is a stateless EJB that I wrote with the Generic DAO pattern. To make it an EJB I had to add a @Stateless annotation and get the EntityManager injected into the bean. What about transactions?

For a stateless EJB the default transaction attribute is REQUIRES, so any method I call on the DAO is executed in a system transaction. If several are called in the same test method they all run in the same transaction.

I've also started using TestNG groups, a great feature. By marking the test method as belonging to the group integration.database I can target it in my TestNG suite assembly in testng.xml:

<suite name="CaveatEmptor-EJB3" verbose="1">

    <test name="Runtime">
        <packages>
            <package name="org.hibernate.ce.auction.test.testng.runtime"/>
        </packages>
    </test>

    <test name="Integration">
        <groups>
            <run><include name="integration.*"/></run>
        </groups>
        <packages>
             <package name="org.hibernate.ce.auction.test.testng.persistence"/>
         </packages>
    </test>

</suite>

I still have to figure out how to create the assembly in a way that says use this runtime for this group of tests. Right now I'd need several suites for this.

Since I'm stuck with the old IntelliJ I've got to run the tests with Ant (I'd really like to have that green bar ;):

<target name="testng.run" depends="testng.package"
    description="TestNG tests with the JBoss EJB3 Microcontainer">
    <mkdir dir="${testng.out.dir}"/>

    <testng outputDir="${testng.out.dir}">
        <classpath>
            <pathelement path="${testng.build.dir}/${proj.shortname}.jar"/>
            <path refid="project.classpath"/>
            <path>
                <fileset dir="${container.lib}">
                    <include name="**/*.jar"/>
                </fileset>
            </path>
        </classpath>
        <xmlfileset dir="${testng.classes.dir}" includes="testng.xml"/>
    </testng>
</target>

So I'm hooked on TestNG now and will use it for all EJB tests in the future. I've got to check out Gavins TestNG configuration for JSF + EJB testing in Seam and how he simulates the HTTP environment...

Oh, and if any Jetbrains guys read this: fix the XML editor. There are people out there who use it to write docs. Thanks :)

17 comments:
 
25. Nov 2005, 07:58 CET | Link
Hani Suleiman | hani(AT)formicary.net
Out of curiosity, why not upgrade to IDEA 5? If there's enough demand I don't mind attempting to port the plugin to IDEA 4.5, but as of right now you're the first person to request it!
ReplyQuote
 
25. Nov 2005, 15:38 CET | Link
Christian
Because the XML editor is broken in IDEA 5, as I said.

 
25. Nov 2005, 20:13 CET | Link
Igor Kuralenok | ik(AT)intellij.com
IntelliJ guys read this :). Please send us failures in XML editor. You can send them directly to me.

IK
 
25. Nov 2005, 22:23 CET | Link
Christian
Both 5.0 and 5.0.1 threw exceptions as soon as I opened XML. One time I lost a few hours of work, after that I didn't touch 5.x any more.

I'm now on 5.0.2 for a whole day and I've only seen a few unrelated exceptions (some missed button event, etc). But I didn't do much XML work. I'll send a bug report if anything should show up later.

 
26. Nov 2005, 00:21 CET | Link
Cedric
Hi Christian,

Glad you are enjoying TestNG, feel free to let me know if you have any questions. Can you elaborate on your "assembly" question at the end of your post?

--
Cedric

 
26. Nov 2005, 01:50 CET | Link
Christian
I guess I had the wrong idea there. Thinking about it, more suites is probably the right strategy to extend this with more tests that have different runtime requirements.
 
28. Nov 2005, 17:33 CET | Link
Christian
UPDATE: If you are going to use CaveatEmptor alpha5 to try this, replace lib/jboss-aop.jar with jboss-aop-5.0.jar.
 
30. Nov 2005, 05:56 CET | Link
J. B. Rainsberger
Christian, when you say that TestNG is "so much better than JUnit", are you comparing TestNG to JUnit 3 or to JUnit 4? If it's JUnit 3, then that's not exactly a fair comparison! If it's JUnit 4, then I'm surprised, because from what I can tell, the two are pretty similar.

Still, I can understand your desire to use an integration testing tool like TestNG for testing EJBs. If there's one lesson I've learned in the last few years, it's that isolated object testing for EJBs ain't worth the effort.

Take care.
 
30. Nov 2005, 16:00 CET | Link
Christian
I didn't try JUnit 4, TestNG does what I want and I only got so much time to spent on evaluating test tools. (The same is true for logging frameworks or any other trivial problem that need a straightforward solution.)

What does isolated object testing have to do with EJB 3.0 beans? They are POJOs, you can test them in any way you like... I could have just called new Foo() and a method on it. But why would I? Isolated unit testing is totally academic, I think almost all useful testing needs some runtime infrastructure and integration.

 
01. Dec 2005, 06:04 CET | Link
Christian
Just because I've got it open right now:

http://docs.jboss.com/seam/reference/en/html_single/#d0e2596

This is how you test an EJB3 bean "outside of a container". Given that my container starts in 2 seconds I don't worry too much about testing inside a container for integration.

 
10. Mar 2006, 01:41 CET | Link
Luigi
I got the latest ejb3 embeddable alpha 5 released in Feb 2006 and couldn't get my stuff to work basing it on the caveatemptor examples.

However I used the examples provided with the embeddable, particularly the 'test-with-junit' and got it working that way.

So check out the EmbeddedEjb3TestCase.java example for further reference. It works with TestNG too.

  
 
07. Jun 2006, 19:33 CET | Link
srikant lakhanpal | srikant.lakhanpal(AT)barco.com
If anybody can provide me a clue to Test EJB3.0 components at server using JUnit4.x
 
11. Dec 2006, 16:26 CET | Link
Christian
If anybody finds this old blog entry, please now use the test setup that is included in the CaveatEmptor download: http://caveatemptor.hibernate.org/

The JPA package includes an EJB3 integration testing superclass with DBUnit support.

 
06. Mar 2007, 00:47 CET | Link
Mike
You should try Ejb3Unit (http://ejb3unit.sourceforge.net) for Ejb3 Testing.
Ejb3Unit automates Entity and Session bean testing outside the container for the EJB 3.0 specification. Ejb3Unit is a JUnit extention and can execute automated standalone junit tests for all EJB 3.0 conform JEE projects.
 
21. Dec 2007, 00:57 CET | Link
Alex

I tried to get EJB3Unit running but failed to get anywhere in a couple hours. It will be nice to get some documentation and tutorials.

 
27. Mar 2008, 05:50 CET | Link
Daniel Wiese

Ejb3Unit 2.0 is extending nicely the Junit framework for ejb3 testing. I am wondering how it could integrate with TestNG?

By the way, the 2.0 version is coming with (http://ejb3unit.sourceforge.net/Roadmap.html):

Improvement: No dependencies - on jar thats it!! (only log4j.jar and optional jmock.jar for mocked tests will be required). This will ease the installation and development in large projects because less dependencies are required. No jar file conflicts anymore!

New Feature: Support for relational CSV data loaders. Load your test data with references!

New Feature: Support for peristence.xml no need to specify your persistence objects for every test!

Improvement: Completely refactored EntityManger life cycle handling - will speed up your testing!

Improvement: Support of the new jMock2 framework!

Improvement: More feedback for failing test cases!

Improvement: Broken entities (e.g. syntax error in query) will not break other tests anymore!

Lots of bug fixes!

 
27. Mar 2008, 05:52 CET | Link
Daniel Wiese

We put a lot of documentation on our home page: http://ejb3unit.sourceforge.net/ - try also the example project - let us know if something is missing - Daniel

Post Comment