Archive

Posts Tagged ‘JUnit’

Groovy + JUnit + Ant

May 29, 2008 Josh 4 comments

I found it extremely difficult over the past couple days to get Groovy and JUnit and Ant to play nicely together. If you have the opportunity to use Maven for your builds, do it. If you’re stuck with Ant, read on.

I’m writing unit tests in Groovy for an application that’s written entirely in Java. That part is easy – Groovy and Java work well together. And since Groovy ignores scope, you can access the private methods you wrote in Java (or Groovy), which makes testing even easier. Rather than using Reflection or calling the public methods that call those private methods, you can call your private methods directly from a Groovy class. Groovy treats them as if they’re public.

To use Groovy + JUnit + Ant, first you need to compile your Groovy files. This part is easy, if you know you have to do it. The groovyc Ant Task has some great examples you can copy and tweak, but make sure you put the groovy-all-VERSION.jar on your classpath. The similarly-named jar without the word “all” in it won’t work.

The hard part about Groovy + JUnit + Ant is this:

“By default Groovy unit test cases generate Java bytecode and so are just the same as any other Java unit test cases. One thing to watch is often Ant / Maven look for *.java files to find unit tests with pattern matching, rather than *.class files.” – Unit Testing (emphasis mine)

Here’s an example from the Ant JUnit Task page:

<junit>
  <!-- some details omitted -->
  <batchtest>
    <fileset dir="${src.tests}">
      <include name="**/*Test*.java"/>
      <exclude name="**/AllTests.java"/>
    </fileset>
  </batchtest>
</junit>

This doesn’t work for Groovy tests, but it should be easy enough to fix – just remove the “.java” extensions, right? Wrong. The JUnit task can find *.java files in your source directory, but not *.groovy files. So you need to change the fileset to point to your classes directory in addition to removing the “.java” suffix from the include and exclude. And if you use closures in your Groovy tests, they’ll get compiled to inner classes in separate files, so you probably want to exclude those from your fileset. Here’s what my task looked like when I finished:

<junit>
  <!-- some details omitted -->
  <batchtest>
    <fileset dir="${classes}">
      <include name="**/*Test*"/>
      <!-- a '$' in the filename means it's an inner class -->
      <exclude name="**/*$*"/>
    </fileset>
  </batchtest>
</junit>

Make sure to add some reporting and code coverage so you can see the statistics from your tests. Happy Anting.

Categories: Groovy Tags: , ,