Recently I posted about evolving the architecture of a markup parser.  During its evolution I ended up completely rewriting the parser to a new architecture.  A solid JUnit test suite made it possible to do this while maintaining confidence in the quality of the new code.  This article details the nature of JUnits that make such a switch easy.

Methodology:

While developing the Textile-J markup parser I incrementally improved the parser by adding support for markup syntax.  Paragraphs were added first, then bold text, then lists, you get the idea.  As support was added for each syntax feature, I created one or more JUnit tests to exercise the feature.  I inspected the results of the HTML output from the small snippet of Textile used, and when I was satisfied created one or more assertions in the JUnit.  This made development easy because:
  • I could isolate the syntax that I wanted to support and test it independently of other syntax
  • Since the tests were small, stepping through the code in the debugger only involved the relevant code
  • It's easy to see when something breaks that worked before
  • I could be confident in the quality of the parser
The Result

The result of using this methodology was a JUnit test suite of over 100 tests, and I could easily measure progress in supporting Textile markup features.

Markup Parser Rewrite

Rewriting the parser first involved stubbing out the new parser API, and then making the old parser API a facade to the new one.  In doing this my new parser API automatically gained over 100 JUnit tests -- which of course were now failing.  By incrementally improving the new parser until all JUnits passed, I could be certain that the new parser supports the same markup language features.

As I finished the last language feature and saw green for every JUnit test, I had a huge sense of relief.  I now knew that the new parser was working with a guaranteed level of quality.

The Textile-J project now has over 250 JUnit tests.  To get an idea what feedback JUnit can give, take a look at the test report here, and the code coverage report here.

Attributes of a Test Oriented Project

The following are some attributes of my project that make JUnit tests so powerful:
  • A JUnit test for every feature
  • Meaningful assertions
  • An environment that makes running JUnits painless and easy (like Eclipse)
  • A development methodology that encourages or requires tests for all new code
  • An Ant build script that runs the JUnits whenever a new build is created
  • Integrated code coverage (such as cobertura) so that you can see which code is tested
Once your project is set up to run tests, it's easy to add them... so jump that first hurdle and get testing with JUnit!