<property name="build.dir" value="target" />
<property name="java.classes" value="${build.dir}/classes" />
<property name="test.classes" value="${build.dir}/test-classes" />
<property name="test.reports" value="${build.dir}/test-reports" />
<property name="lib" value="${build.dir}/lib" />
<path id="test.classpath">¶
<pathelement location="/Users/johnsmart/Projects/Books/jenkins-the-definitive-guide/hudsonbook-content/tools/junit/*.jar" />
<pathelement location="${java.classes}" />
<pathelement location="${lib}" />
</path>
<target name="test" depends="test-compile">
<junit haltonfailure="no" failureproperty="failed">·
<classpath> ̧
<path refid="test.classpath" />
<pathelement location="${test.classes}" />
</classpath>
<formatter type="xml" />¹
<batchtest fork="yes" forkmode="perBatch"º todir="${test.reports}">
<fileset dir="${test.src}">»
<include name="**/*Test*.java" />
</fileset>
</batchtest>
</junit>
<fail message="TEST FAILURE" if="failed" />¼
</target>
¶ We need to set up a classpath containing the junit and junit-ant JAR files, as well as the
application classes and any other dependencies the application needs to compile and run.
· The tests themselves are run here. The haltonfailure option is used to make the build fail
immediately if any tests fail. In a Continuous Integration environment, this is not exactly what we
want, as we need to get the results for any subsequent tests as well. So we set this value to no and
use the failureproperty option to force the build to fail once all of the tests have finished.
̧ The classpath needs to contain the JUnit libraries, your application classes and their dependencies,
and your compiled test classes.
¹ The Junit Ant task can produce both text and XML reports, but for Jenkins, we only need the
XML ones.
º The fork option runs your tests in a separate JVM. This is generally a good idea, as it can avoid
classloader issues related to conflicts with Ant’s own libraries. However, the default behaviour of
the JUnit Ant task is to create a new JVM for each test, which slows down the tests significantly.
The perBatch option is better, as it only creates one new JVM for each batch of tests.
» You define the tests you want to run in a fileset element. This provides a great deal of flexibility,
and makes it easy to define other targets for different subsets of tests (integration, web, and so on).
¼ Force the build to fail after the tests have finished, if any of them failed.
If you prefer TestNG, Ant is of course well supported here as well. Using TestNG with the previous
example, you could do something like this: