Categories
Agile Java Software

An alternative approach to creating specs from JUnit tests

I’m a convert to Behavior-Driven Development, or BDD, as championed by people like Dan North and Dave Astels. As a first step, I wanted to be able to generate a report from an existing collection of JUnit tests which read more like a set of specs (this would be in addition to the normal success/fail/error report), which would in turn be an encouragement to think in terms of behaviour specification when writing tests for new functionality.

To begin with, TestDox looked like just the job. Unfortunately, when I tried it I came across a few things that weren’t quite perfect for my situation:

  • It makes hardcoded assumptions about your test naming convention. For some reason we seem to have developed a local test suite naming convention of *Tests.java, instead of the more normal *Test.java or Test*.java.
  • It generates a single page of output, which gets unwieldy when you have a large number of tests
  • It flattens the package structure, which makes it hard to find the specs for a particular class, especially if there are similarly-named test suites in different packages.
  • It doesn’t include tests/specs which are inherited from a parent class.

While I could have probably solved most of these by modifying the code for TestDox, it got me thinking about whether there might be a different way of doing it. After a few false starts, I settled on the idea of writing a custom stylesheet for the JUnitReport ant task.

What I ended up with was the file below:


    
    
    
    
    
    
    
    
        
        
            
        
        
        
        
            
        
        
        
        
            
        
        
        
        
            
        
        
        
        
            
                
                    
                
            
            
                
                    
                
            
        
    
    
    
        
            
                Behaviour specifications
            
            
                
                
                
                    <h2>Frame Alert</h2>
                    <p> This document is designed to be viewed using the frames feature. If
                        you see this message, you are using a non-frame-capable web
                        client. </p>
                
            
        
    
    
    
        
    
    
        
            
                
                Behaviour specifications
            
            
                

Behaviour specifications

Select a package on the left to view the specifications for classes in that package.

Packages

Packages

.html packageFrame Behaviour specifications: <xsl:value-of select="$local-name"/>

Behaviour specifications:

  • Derived from reports generated by JUnit and Ant.


    default-package

    To use it, simply save junit-frames.xsl to a convenient directory, and point your ant JunitReport task to that directory (xslt in the example below). If you’ve already run a “normal” JunitReport, you’ll need to tell it to ignore the suites file that this creates:

    
        
        
    
    

    The only slight gotcha is that it relies on the Linkwerk regular expression extension, which means you need to have lw-regexp-util-1.0.0.jar in your classpath when you run ant (either by copying it to $ANT_HOME/lib, or by having it in the system classpath when you run ant). As far as I can figure, you can’t work round this using a taskdef, because of the same classloader issues that mean you always end up copying junit.jar into ant’s lib dir too.

    What you should get is a report with the package names listed in the left frame, linked to a page for each package containing its specs. So for example, if you a test suite like this:

    package org.whoever.foo;
    
    import junit.framework.TestCase;
    
    public class TestANewlyInitialisedFoo extends TestCase {
    
        public void testShouldHaveZeroLength() {
            ...
        }
    
        public void testShouldHaveNoMembers() {
            ...
        }
    
        public void testShouldThrowExceptionOnPop() {
            ...
        }
    }
    

    You’ll end up with a section in the org.whoever.foo report looking a bit like this:

    A newly initialised foo

    • should have zero length
    • should have no members
    • should throw exception on pop

    Here’s a screenshot of the actual output. Don’t pay too much attention to the actual test names, most of which weren’t written using a BDD approach.

    picture-1.png

    5 replies on “An alternative approach to creating specs from JUnit tests”

    […] Venendo ad un po’ di codice, il primo passo per incamminarsi su questa strada può essere quello di utilizzare un semplice xsl sui report prodotti da JUnit, per cominciare a misurare quanto ad oggi, siamo orientati alle specifiche ed ai comportamenti, invece che alle classi ed ai metodi. Tale xsl assume che ogni test JUnit sia una collezione di specifiche, ad esempio scritta un questo modo: Java [Show Styled Code]: […]

    Don’t you think it’s idiocy to use 2000-feet-high divs with horizontal scrollbar below? To scroll horizontally it’s first lines, one must scroll the page down, and then up.

    Don’t you think it’s idiocy to use 2000-feet-high divs with horizontal scrollbar below?

    OK, I’ve tweaked the CSS for IG Syntax Highlighter a little from the defaults. Hopefully that’s better.

    Leave a Reply