Tuesday, May 24, 2011

a TDD framework for EJB3

In Container Test Driven Development for EJB3

Want to write code TDD style but using JEE? Well now you can!

The blog post I did many months ago has now found its way into a useful tool (hopefully).

Background
As most time I write code in Spring or JEE5 environments I have had the opportunity to become partially spoiled by the relative ease of testing Spring "wired" code. The only trouble I have had is basically connected to transactions (the test committed unwanted data) or that I need a small variation of the configuration and the easiest way to do this was do create a new copy of the spring-config (config-hell-yuck).

My experience with TDD 
My experience with the TDD "in-container" approach is aprox 4 years and have written about thousand tests of various types. I think I have a decent experience in the subject, but still have a lot to learn.

TDD, the test driven development.
I have during my years as a developer started to classify the way my tests are written into four categories.
  1. Unit Test, a single class with no relations. (Hard to do in real life for "service layered applications" but its the way to start with TDD). This always just works as no related classes are loaded during its test i.e. no In-Container tooling is needed.
  2. Functional Test, the entire application is "started" somehow and all internal code can be executed without exception. (This is how the Spring-JUnit extensions works). This requires some sort of In-Container testing.
  3. Mocking(Partially functioning) Test, The test can be started as a functional test or as a regular unit test but some parts are in need of mocking. I usually do this for third-party dependencies that I can not do In-Container testing of. Not easy in any tool, in Spring a new config must be created for each type of test.
  4. UseCase Test, this test is done to verify the specification. Its a playback of the intended software usage, for these tests to be easy to maintain and keep in control its a good thing to try to minimize the amount to something manageable. Like max 100 or so. The software I personally tried this "test-type" first time had about 60 (for a peace of software that was about 100k line of code). The interesting thing is that the requirements that we created it from had only 15 use case scenarios. According to me each test here hould have a corresponding use case scenario. The tip is to try to code the test in way that its easy to read as a scenario even though its code. 
If I look at my personal experience the functional tests are the once where i easily can test the code i create without hideous overhead or "meaningless" test code. The second most important one is the mocking test, where i try to not execute some part of the code. This is very useful for fixing bugs in legacy systems where parts are just not easy to run In-Container and for excluding a third party software from the test assertions.
Once the software is "done" i start creating the use-case scenario test and make it "really work". This use case tests can be written earlier to understand all parts of the software in creation.

- Unit Tests are used to verify utilities or classes that have no dependencies. Very good as long as they can be used.
- Function/Mocking test is short and concise and have focus on assertions. There are large amounts of these test. 
- The Use case test is complex and large flows are executed, only key elements are asserted. Never assert any business logic details, just big picture flows.

This is what i learned when coding Spring code. And 2 years ago I went back to JEE .... OMG! Its like stepping back to stoneages, TDD wise. The "TDD bug" had already stung me, I could no longer code without testing. It felt dirty and I felt like i did not have control over the software I was suppose to code.

A possible solution?

It's time to announce a working version of the TDD Tooling for EJB3 :)

In an effort to try to create a tool that can support the four different types of tests that are described above a tooling framework was created that makes it easy to test JEE code. At least it seems to work as intended, i need more to use to prove it though :)

I am personally using it for two separate customers with very good results. The framework is adapted for one of them and used as is for the other. I have personally educated the first customers in TDD coding and shown how we can code in a mix of EJB2/3 and Factories with this tool.

See this presentation from the Javaforum in Gothenburg.
This explains how you can perform Functional and Mocking tests.

Introducing TDD tooling for JEE based code. 

Pros
- Loose coupling to your test code, and no coupling to your business code.
- Automated lifecycle handling of underlying Container and DB transactions.
- Possible partial mocking of any EJB3 service (recommend Mockito or manual mocks).
Semi-pro (proven concept)
- Has been in use by two development teams since january 2011 and over 300 tests are executed with this tool for both projects (at this precise moment). 

Cons
- Only supports part of the JEE specification.
@Stateless, @Stateful, @EJB and @PostConstruct are verified all other part are unverified and might work, but not intentionally.
- Not supported by any companies. (So far)

Thats it from me for now, hope that someone start using this and gives some feedback to me soon :)

Maven dependency example:


<dependency>
    <groupid>org.hrodberaht.inject.extension</groupid>
    <artifactid>tdd</artifactid>
    <version>1.0_RC2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupid>org.mockito</groupid>
    <artifactid>mockito-all</artifactid>
    <version>1.8.5</version>
    <scope>test</scope>
</dependency>



Assemply JAR with same dependencies included as the maven dependencies above.
http://code.google.com/p/injection-extensions/downloads/list



No comments: