Enhance the Unit test using Annotation approach

August 28 2007No Commented

Categorized Under: Java, Software Engineer

New unit test tools base on Java 5 annotation features provide the better approach of re-use test code. JUnit4 provides the excellent annotation RunWith. The description of RunWith is copied from Junit4 javadoc:

"When a class is annotated with @RunWith or extends a class annotated with @RunWith, JUnit will invoke the class it references to run the tests in that class instead of the runner built into JUnit. We added this feature late in development. While it seems powerful we expect the runner API to change as we learn how people really use it. Some of the classes that are currently internal will likely be refined and become public. For example, suites in JUnit 4 are built using RunWith, and a custom runner named Suite:

 
  @RunWith(Suite.class)
  @SuiteClasses(ATest.class, BTest.class, CTest.class)
  public class ABCSuite {
   ...
  }
 

By using RunWith annotation, we can custom the way of running unit test. While writing the unit test code, I face with the following problems:

  1. Re-usability of code for initiating objects using in test cases (in setUp method)
  2. Re-usability of code while running test cases (in test methods)

The easiest approach of avoid duplicating code is create the parent unit test and all test cases are inherited from this parent class, or we create the common static functions and call it every where in test class. At the first time, I choose the way of creating the parent test cases and all test cases will inherit it, but this solution has some disadvantages:

  1. The parent test case must have the test method, if not build tool likes Maven will throw an error.
  2. The test cases run like JUnit3 approach that we must extend the parent test (like TestCase). I prefer the solution has pure test case that does not inherit from any parent class
  3. Divide the test case into smaller units. For testing service unit test, some methods that support transaction and some are not. So we must divide our test case into 2 smaller ones, one extends from ParentNoTransactionTestCase and one extends from ParentTransactionSupportTestCase.

I have maintained nearly 70 test cases and it will grow fast daily. A lot of test code is written and I do not want to repeat the test code over test cases but I want to have a clean solution. I wish my test code run in a Runner class, it can manage the objects via annotation. Instead of initiate the object like this in setUp method:

 
class ATest{
  private WicketTester wicketTester;
 
  @Before
  public void setUp() {
    String[] beanNames = appContext.getBeanDefinitionNames();
    AnnotApplicationContextMock appContextMock = new AnnotApplicationContextMock();
 
    for (String beanName : beanNames) {
      appContextMock.putBean(beanName, appContext.getBean(beanName));
    }
 
    owsWebApp = new OwsMockWebApplication();
    owsWebApp.addComponentInstantiationListener(
      new SpringComponentInjector(owsWebApp, appContextMock));
 
    wicketTester = new WicketTester(owsWebApp);
 
  }
}

I like the annotation like this:

 
class ATest {
 
  @WicketTester
  private WicketTester wicketTester;
 
  @Before
  public void setUp() {
    ...Other specific code for this test case
  }
}

We can change the normal approach of running test case by extending the Runner class of JUnit4 (we likely extend class org.junit.internal.runners.TestClassRunner). However, there is one testing framework can help us reduce a lot of effort of extending annotation testing, it is Unitils (why we need re-invent the wheel?). My next post will introduce the way of extending Unitils that supports more features base on my current works. I do not invest much on TestNG and I am wonder whether TestNG provides the easy way to extend its functionalities like JUnit4 provides.

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • BarraPunto
  • Bitacoras.com
  • blinkbits
  • BlinkList
  • blogmarks
  • BlogMemes
  • BlogMemes Cn
  • BlogMemes Fr
  • BlogMemes Jp
  • BlogMemes Sp
  • Blogosphere News
  • Blogsvine
  • blogtercimlap
  • Book.mark.hu
  • Bumpzee
  • co.mments
  • connotea
  • De.lirio.us
  • Design Float
  • DotNetKicks
  • DZone
  • eKudos
  • email
  • Fark
  • Faves
  • feedmelinks
  • Fleck
  • Furl
  • GeenRedactie
  • Global Grind
  • Gwar
  • Haohao
  • HealthRanker
  • Hemidemi
  • Identi.ca
  • IndianPad
  • Internetmedia
  • kick.ie
  • Kirtsy
  • laaik.it
  • Leonaut
  • LinkaGoGo
  • LinkArena
  • LinkedIn
  • Linkter
  • Live
  • Ma.gnolia
  • Meneame
  • MisterWong
  • MisterWong.DE
  • muti
  • MyShare
  • MySpace
  • N4G
  • Netvibes
  • Netvouz
  • NewsVine
  • NuJIJ
  • Ping.fm
  • PlugIM
  • Pownce
  • ppnow
  • Print
  • Propeller
  • Ratimarks
  • Rec6
  • Reddit
  • SalesMarks
  • Scoopeo
  • scuttle
  • Segnalo
  • Shadows
  • Simpy
  • Slashdot
  • Smarking
  • Socialogs
  • SphereIt
  • Spurl
  • StumbleUpon
  • Symbaloo
  • Taggly
  • TailRank
  • Technorati
  • ThisNext
  • Tipd
  • Tumblr
  • TwitThis
  • Upnews
  • Webnews.de
  • Webride
  • Wikio
  • Wikio FR
  • Wikio IT
  • Wists
  • Wykop
  • Xerpi
  • Yahoo! Buzz
  • YahooMyWeb
  • Yigg

Leave a Reply