Run all unit tests with Ant builder - java

I have a directory with a bunch of JUnit tests in my project. So far I have used separate target for each unit test. For example:
<target name="MyTest">
<mkdir dir="${junit.output.dir}"/>
<junit fork="yes" printsummary="withOutAndErr">
<formatter type="xml"/>
<test name="tests.MyTest" todir="${junit.output.dir}"/>
<classpath refid="MyProject.classpath"/>
</junit>
</target>
This method requires me to change build file every time I add a Unit test.
I want to able able to to run all unit tests in the project with a single Ant builder target. Is it possible to do?

Yep it is, you need to look at the fileset tag, e.g:
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<pathelement location="${build.tests}"/>
<pathelement path="${MyProject.classpath}"/>
</classpath>
<formatter type="xml"/>
<batchtest fork="yes" todir="${reports.tests}">
<fileset dir="${src.tests}">
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>
The important part is the use of fileset and a glob/wildcard pattern to match the names of the tests. Full docs on the junit task with examples here:
http://ant.apache.org/manual/Tasks/junit.html

Yep! We do it using an ant command batchtest. Looks like this:
<batchtest todir="${junit.report.dir}">
<fileset dir="${basedir}\test\unit">
<include name="**/*Test.java" />
</fileset>
</batchtest>
Google it, it should sort you out

Related

JUnit Ant ClassNotFoundException

I am getting a java.lang.ClassNotFoundException when I run my target TranslatorWorkflow that is supposed to execute a JUnit test. I am running a build.xml file with the targets: build TranslatorWorkflow. It compiles but fails on the JUnit test immediately.
My TranslatorWorkflow.class file is in {basedir}/bin/testScripts/. My classpath and target are:
classpath:
<path id="classpath">
<fileset dir="${basedir}/lib/binaries" includes="*.jar" />
<pathelement location="${basedir}/bin/testScripts/" />
</path>
TranslatorWorkflow target in my build.xml file:
<target name="TranslatorWorkflow">
<mkdir dir="${junit.output.dir}" />
<junit fork="yes" printsummary="withOutAndErr">
<formatter type="xml" />
<test name="testScripts.TranslatorWorkflow" todir="${junit.output.dir}" />
<classpath refid="classpath" />
</junit>
</target>
I attempted to emulate this answer to a similar question by adding the pathelement line shown in my classpath section above, but received the same exception. I've looked at this question as well as it seems like the same deal. I'd imagine there is something super obvious that I'm missing but alas I don't seem to be getting it.
The classpath should reference ${basedir}/bin not ${basedir}/bin/testScripts (i.e. it should reference the root of classes directory, not the package in which the class exists):
<path id="classpath">
<fileset dir="${basedir}/lib/binaries" includes="*.jar" />
<pathelement location="${basedir}/bin/" />
</path>
Dumpcats, try this...
<path id="base.path">
<pathelement path="${sun.boot.class.path}"/>
<pathelement path="${sun.boot.library.path}"/>
<fileset dir="${basedir}">
<include name="**.jar"/>
</fileset>
</path>
And then in the target element ...
<target name="runTest">
<mkdir dir="test_reports"/>
<junit
fork="true"
forkmode="once"
maxmemory="256m">
<formatter type="plain" usefile="false"/>
<formatter type="xml"/>
<classpath refid="base.path"/>
<batchtest
haltonerror="true" haltonfailure="true"
todir="test_reports">
<fileset dir="${test.build}">
<include name="**/*Test*.class"/>
<include name="**/Test*.class"/>
<include name="**/*Test.classp"/>
<!-- Exclusions -->
<exclude name="**/util/*.class"/>
</fileset>
</batchtest>
</junit>
</target>
At least is that is how i manage classpath reference and everything works like a charm.

Ant JUnit Batchtest .java or .class

I have seen a few links which appears to imply that JUnit tests can be executed from the .java file instead of the .class
For example
<junit printsummary="yes" haltonfailure="yes" haltonerror="yes">
<classpath refid="ui.tests.classpath"/>
<formatter type="xml"/>
<batchtest todir="${env.WORKSPACE}/UITests/output">
<fileset dir="${ui.tests.classes}">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
</junit>
Instead of
<junit printsummary="yes" haltonfailure="yes" haltonerror="yes">
<classpath refid="ui.tests.classpath"/>
<formatter type="xml"/>
<batchtest todir="${env.WORKSPACE}/UITests/output">
<fileset dir="${ui.tests.classes}">
<include name="**/*Test.class"/>
</fileset>
</batchtest>
</junit>
Is the first example a valid case? I could not get it working due to ClassNotFoundExceptions
I agree with the comment above, that it looks like the tag allows for either .java or .class.
I did a small test and when I ran a test with this setup - where the dir=somefolder, then using <include name="**/*Test.java"/> when the folder pointed at contains class files, then Ant will basically have an empty fileset to process for *Test.java, but when using <include name="**/*Test.class"/> then the fileset was not empty and the test cases will get run.
This was the result of my quick test. As far as I could tell, it looks like you need to specify the *Test.class to pickup the test cases.

How do you execute a subset of JUnit tests using Ant?

We have a large project and executing all our unit tests takes a lot of time. We are also using Ant. What strategies could be used to execute only a subset of our tests using Ant? We have our tests in groups of logical java packages, so that could be of help...
You should use batchtest tag of the junit ant task. Check here : http://ant.apache.org/manual/Tasks/junit.html
A simplified example from that link is given below:
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<pathelement location="${build.tests}"/>
<pathelement path="${java.class.path}"/>
</classpath>
<formatter type="plain"/>
<batchtest fork="yes" todir="${reports.tests}">
<fileset dir="${src.tests}">
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>

taking output on console when running junit through ant script

I am using ant script and running a junit, the problem I am facing is that I am unable to get the output on console, rather I get the output in a log file.
how can I achieve that..
I am using the following script.
<target name="validate_mapping" description="Testing the Hibernate ">
<path id="validator.classpath">
<fileset dir="${basedir}\lib">
<include name="Junit-Temp-Test.jar" />
</fileset>
</path>
<junit printsummary="yes">
<formatter type="plain"/>
<test name="com.ofss.fc.junit.test.SampleTest" />
<classpath>
<path refid="validator.classpath" />
<path refid="lib.ext.classpath" />
</classpath>
</junit>
</target>
I think you need to specify "usefile" attribute <formatter usefile="false" type="plain"/>

Junit Ant Task, output stack trace

I have a number of tests failing in the following JUnit Task.
<target name="test-main" depends="build.modules" description="Main Integration/Unit tests">
<junit fork="yes"
description="Main Integration/Unit Tests"
showoutput="true"
printsummary="true"
outputtoformatters="true">
<classpath refid="test-main.runtime.classpath"/>
<batchtest filtertrace="false" todir="${basedir}">
<fileset dir="${basedir}" includes="**/*Test.class" excludes="**/*MapSimulationTest.class"/>
</batchtest>
</junit>
</target>
How do I tell Junit to ouput the errors for each test so that I can look at the stack trace and debug the issues.
You'll need to add the formatter task as a child of the batchtest task (NOT as the immediate child of the junit task)
The syntax of formatter is:
<formatter type="plain" usefile="false"/>
type can be one of plain, brief, xml or failure.
usefile="false" asks Ant to send output to the console.
Scroll down to the h4 on "formatters" at http://ant.apache.org/manual/Tasks/junit.html for more details.
The answer was to add the tag within the tag.
<target name="test-main" depends="build.modules" description="Main Integration/Unit tests">
<junit fork="yes"
description="Main Integration/Unit Tests"
showoutput="true"
printsummary="true"
outputtoformatters="true">
<classpath refid="test-main.runtime.classpath"/>
<batchtest filtertrace="false">
<fileset dir="${basedir}/out/test/common" includes="**/*Test.class" excludes="**/*MapSimulationTest.class"/>
<fileset dir="${basedir}/out/test/test-simulation" includes="**/*Test.class" excludes="**/*MapSimulationTest.class"/>
</batchtest>
<formatter type="brief" usefile="false"/>
</junit>
</target>

Categories