Groovy 2.0 Hint: @NotYetImplemented

Groovy 2.0 comes with a brand new AST transformation that is supposed to be applied on certain test methods: @NotYetImplemented. Initially introduced by Marc Guillemot [0] in HtmlUnit [1] and already implemented by GroovyTestCase.notYetImplemented [2], this time it leverages Groovy's AST transformation mechanism.

Applying @NotYetImplemented

@NotYetImplemented's functionality is pretty easy to describe: it inverts test case results. Thus, if a test method is annotated with @NotYetImplemented it will fail if it otherwise would succeed and vice versa. The implementation is pretty generic, therefore the annotation can be applied on JUnit 3/4 test methods and used in Spock [3] specifications. Let's take a look at the following test case:
 

class PersonTests extends groovy.util.GroovyTestCase {
 
    static class Person {
        String name
        Date   birthdate
 
        def age() {
            0
        }
    }
 
    void testComputeAge() {
        def p = new Person(name: 'John Doe', birthdate: Date.parse('dd.MM.yyyy', '01.01.1970'))
        assert 42 == p.age()
    }
}

 
Person.age() has not been implemented yet - it simply returns 0. Thus the test case fails with the the following AssertionError:
 

There was 1 error:
1) testComputeAge(PersonTests)Assertion failed: 

assert 42 == p.age()
          |  | |
          |  | 0
          |  PersonTests$Person@538edf3c
          false

	at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:386)

 
What to do if we do not want to remove but implement age() in the next iteration, as it isn't planned to use it in the source base anytime soon? We would have to uncomment our test method in order to let our test-suite execute successfully. This is the time @NotYetImplemented comes into play. When applying @NotYetImplemented on our test method, the test method will succeed at execution time - because the actual test method fails (inversion).
 

class PersonTests extends groovy.util.GroovyTestCase {
 
    static class Person {
        String name
        Date   birthdate
 
        def age() {
            0
        }
    }
 
    @NotYetImplemented 
    void testComputeAge() {
        def p = new Person(name: 'John Doe', birthdate: Date.parse('dd.MM.yyyy', '01.01.1970'))
        assert 42 == p.age()
    }
}

 
Et voilĂ , the test case turns green (assuming it's executed with a test runner visualizing successful tests with a green bar ;))! If the age() implementation would change to
 
def age() {
    42
}
 
the execution of PersonTests would fail with:
 
There was 1 failure:
1) testComputeAge(PersonTests)junit.framework.AssertionFailedError: Method is marked with @NotYetImplemented but passes unexpectedly
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 
As long as the test method is annotated properly, an AssertionFailed error is thrown if the test method passes unexpectedly.

Conclusion

@NotYetImplemented can be used to invert test case results. This is helpful to implement test methods that don't currently work but should work in a few iterations. As its implementation is fairly generic it can be applied in JUnit 3, JUnit 4 and Spock test methods. The AST transformation is a result of the Gr8Conf EU hackergarten, special thanks to all contributors!

[0] Marc Guillemot - http://mguillem.wordpress.com/about/
[1] HtmlUnit - http://htmlunit.sourceforge.net/
[2] GroovyTestCase.notYetImplemented
[3] Spock