Sbiera Bogdan Sbiera Bogdan - 3 months ago 9
Java Question

Ant script to run unit tests from multiple modules and fail the build if a test fails

My project has several modules, each having its own build script with a target called "unit-tests"(which runs the unit tests). I created an Ant script that calls the "unit-tests" targets in the modules, runs all the tests and after that generates a

junitreport
from the output of the executed tests(which is saved in xml files). So far so good, but what I want now is to fail the build if at least one test has failed.

My script now looks something like this, and I need some method of finding out if a the unit tests failed.(I know about the
failureproperty
in the
junit
task but I don't know how I could pass that to the calling script)

....
<target name="run-unit-tests" depends="init-output">
<ant antfile="${module1}/build.xml" inheritAll="false" target="${junit-target}" />
<ant antfile="${module2}/build.xml" inheritAll="false" target="${junit-target}" />
....
</target>

<target name="default" depends="run-unit-tests">
<junitreport todir="${junit.report.dir}" tofile="TEST-UnitTestSuites.xml">
<fileset dir="${junit.output.dir}">
<include name="**/TEST-*.xml" />
</fileset>
</junitreport>

//---->fail the build if at least one unit tests has failed
</target>


Any ideas are greatly appreciated. Thanks :)

Answer

After trying to come up with all sort of "tricks" to get this to work i finally found a method that I'm happy about. I defined for each module's build.xml file a target:

<junit failureproperty="testsFailed" showoutput="true">         
        ...
        <formatter type="xml" />
</junit>
<fail if="${testsFailed}" message="Some of the unit tests failed." />
<!-- the fail task throws an exception if ${testsFailed} is true -->

This executes the unit tests in a module and if any test failed it throws an exception. It also logs the junit output in an xml file. In the tests.xml build file I have something like this:

<target name="run-unit-tests" >
    <run-tests location="${module1.location}" />
    <run-tests location="${module2.location}" />
</target>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Writes the results of the unit tests in a junit report        -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<target name="unit-tests" depends="run-unit-tests">
    <junitreport todir="${junit.report.dir}" tofile="TEST-UnitTestSuites.xml">
        <fileset dir="${junit.output.dir}">
            <include name="**/TEST-*.xml" />
        </fileset>
    </junitreport>
    <fail if="${testsFailed2}" message="Some of the unit tests failed." />
</target>

<macrodef name="run-tests">
    <attribute name="location" />
    <sequential>
        <trycatch>
            <try>
                <echo message="@{location}" />
                <if>
                    <available file="@{location}/build.xml" />
                    <then>
                        <ant antfile="@{location}/build.xml" inheritAll="false" target="${junit-target}" />
                    </then>
                </if>
            </try>
            <catch>
                <property name="testsFailed2" value="true" />
            </catch>
        </trycatch>
    </sequential>
</macrodef>

If the tests in a module fail, the exception is caught and sets the testsFailed2 property.Now all the tests are run and the junit outputs are saved in the same folder. The unit-tests target creates a single xml report from all the tests outputs( this report can be used for continuous integration builds) and the ant script will the fail if any unit test failed. Hope this helps someone :)

Comments