Groovy Feature: Testing Source Code in Comments

Groovy comes with a seemingly endless number of simplifications for programmers. One of them is a class called JavadocAssertionTestSuite [0].

Source Code Examples in JavaDoc Comments

Especially for library/framework provides it makes sense to visualize usage of certain components within JavaDoc comments. Even though JavaDoc Jars may not be manually imported by most programmers, IDEs offer a way to show JavaDoc for methods, classes etc. in a rich-text view by using a keyboard shortcut. When using JavaDoc, more than one line source code examples are wrapped by a <pre> tags. For example, see the following example from the java.nio.file.Files#newOutputStream() method:
 
    Path path = ...
    // truncate and overwrite an existing file, or create the file if

    // it doesn't initially exist

    OutputStream out = Files.newOutputStream(path);
    // append to an existing file, fail if the file does not exist

    out = Files.newOutputStream(path, APPEND);
    // append to an existing file, create file if it doesn't initially exist

    out = Files.newOutputStream(path, CREATE, APPEND);
    // always create new file, failing if it already exists

    out = Files.newOutputStream(path, CREATE_NEW);
 
As code gets changed over time, an interesting question is how to ensure code validity for source code examples embedded in JavaDoc comments. That is where Groovy jumps in. Groovy comes with JavadocAssertionTestBuilder and JavadocAssertionTestSuite. Source code examples within documentation for classes owned by a JavadocAssertionTestSuite can be annotated with
 
<pre class="groovyTestCase">
 // source code example here
</pre>
Each section formatted with the CSS class groovyTestCase is found by the test suite and executed within runtime-generated test methods.

Automatically Testing Source Code Examples

So let's assume we do have a utility class Euro responsible to wrap BigDecimal values and add some EUR-specific functionality. One method is the toString method that properly formats the current EUR object.
 

class Euro {

    def Euro(BigDecimal amount) { /* ... */ }

    /**
      * Formats the current EUR object.
      *
      * <pre class="groovyTestCase">
      *    def eur = new Euro(10.42)
      *    assert '10,42 €' == eur as String
      * </pre>
      **/
    String toString() { /* ... */ }
}

 
With JavadocAssertionTestSuite we can run this test case written in GroovyDoc during test suite execution. The only thing we need to manage is to add the test suite to our test suite implementation:
 

class MyTests extends TestCase {

  static TestSuite suite()  {
    def suite = new TestSuite()
    suite.addTest( JavadocAssertionTestSuite.suite( 'src/main' ) )
    suite
  }

  // other tests ...

}

 
The suite method needs to be called with a base directory, in the example this is src/main. All *.java and *.groovy files in this directory and above are included. Yes, it is even possible to annotate Java classes with Groovy source code tests. There are two more suite methods, which allow for the specification of include and exclude patterns on the files names.

Conclusion

JavadocAssertionTestSuite is a nice, hidden feature that can be used to execute test code embedded within Java/GroovyDoc documentation.

[0] JavadocAssertionTestSuite