As I wrote about previously, TestNG can execute an existing suite of JUnit tests, thus providing a unified reporting mechanism for all developer tests. This means that TestNG can also execute developer test written in Groovy.
In order for this process to work, however, you must compile any Groovy tests into byte code and add references in TestNG’s testng.xml file. You can either:
-
Reference the corresponding class directly or
-
Reference the package the class resides in
and ensure that the junit attribute of the test element these classes are defined in is set to true.
The following test, for instance, defined in a testng.xml file, is designated as a JUnit test. It will be run JUnit style– a fixture (if defined) for every test found in the class.
<test name="junits" junit="true">
<classes>
<class name="test.com.acme.sedo.frmwrk.filter.impl.ClassInclusionTest" />
</classes>
</test>
In order to run all copasetic unit tests (defined in both TestNG and Groovy) in an Ant build, I create a TestNG task, which depends on a compilation of Groovy files, shown below.
<groovyc destdir="${classesdir}"
srcdir="./test/groovy" >
<classpath>
<path refid="build.classpath"/>
<pathelement path="${testclassesdir}"/>
<pathelement path="${classesdir}"/>
</classpath>
</groovyc>
The task above compiles any associated Groovy tests (found in the test/groovy directory) and puts the class files in a specific location.
Now, when testng-unit is invoked, any corresponding hip tests written in Groovy will be compiled into normal .class files and therefore picked up by TestNG (and run as normal JUnit tests). The TestNG task is accordingly defined to pick up a testng.xml file designated for running unit tests.
<target name="testng-unit" depends="compile,groovy-compile">
<testng outputDir="${testng.output.dir.unit}"
sourceDir="${testng.source.dir}"
classpath="${testclassesdir};${classesdir}">
<xmlfileset dir="${testng.suitexml.dir}"
includes="${testng.suitexml-unit.name}"/>
<classpath>
<path refid="build.classpath"/>
</classpath>
</testng>
</target>
Now that this process has been defined, I can write tests in either JUnit, TestNG, or even Groovy and one runner will run them all. Dig it, man?