Running Groovy tests in NetBeans 6.7.1

30 08 2009

I’m a long-time Eclipse user, but I heard that NetBeans has better (for the time being) Groovy support.  To see what it was all about I downloaded and installed NetBeans 6.7.1.  While I was attending the No Fluff Just Stuff conference this weekend I tried following along with a Groovy testing session by plugging the examples into NetBeans.  We created a mix of Java and Groovy tests inside a Java project, but when I ran the test suite only the Java tests ran.

I dug through the generated build-impl.xml file to find out why, and found that JUnit is being passed a list of .java files.  The Groovy tests are .groovy, so they won’t run.  JUnit will accept .class files, and since Java and Groovy are compiled to .class files by NetBeans tests in both languages will run this way.  I edited build.xml and overrode three targets from build-impl.xml.  With these changes you can run individual Java and Groovy tests or run them as part of a full test run.  I highlighted the changes I made from the original build-impl.xml targets in red.  If you copy/paste the xmlns attribute and these targets into build.xml you should be able to run all of your Groovy and Java tests in NetBeans.

Note: Be sure to edit build.xml, not build-impl.xml since it can regenerate and overwrite your changes.  Yes, I found this out the hard way 🙂

build.xml:

<?xml version="1.0" encoding="UTF-8"?>

<project name="TestGroovy" default="default" basedir="." xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3">
    <description>Builds, tests, and runs the project TestGroovy.</description>
    <import file="nbproject/build-impl.xml"/>

    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
        <j2seproject3:junit testincludes="**/*Test.class"/>
    </target>

    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
        <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpath="${javac.classpath}"/>
        <groovy>
            properties."test.includes.class" = properties."test.includes".split("\\.")[0] + ".class"
        </groovy>
        <j2seproject3:junit excludes="" includes="${test.includes.class}"/>
    </target>

    <target name="-init-macrodef-junit">
        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <sequential>
                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
                    <batchtest todir="${build.test.results.dir}">
                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
                            <filename name="@{testincludes}"/>
                        </fileset>
                    </batchtest>
                    <classpath>
                        <path path="${run.test.classpath}"/>
                    </classpath>
                    <syspropertyset>
                        <propertyref prefix="test-sys-prop."/>
                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
                    </syspropertyset>
                    <formatter type="brief" usefile="false"/>
                    <formatter type="xml"/>
                    <jvmarg line="${run.jvmargs}"/>
                </junit>
            </sequential>
        </macrodef>
    </target>
</project>