Search code examples
antjacocomacrodef

Running Ant macro from within Jacoco's coverage task


My project is using Ant and it has several test suites. Since each suite is ran in a similar way, there is a macro defined:

<macrodef name="exec-tests">
    <attribute name="test-suite" />
    <element name="test-run" implicit="yes" />
    <sequential>
        <junit printsummary="yes" haltonfailure="true" haltonerror="true" showoutput="true" outputtoformatters="true" fork="true" maxmemory="512m">
            <jvmarg value="-XX:MaxPermSize=256m" />
            <jvmarg value="-Xmx512m" />
            <jvmarg value="-Xms512m" />
            <classpath refid="test.run.class.path" />
            <formatter type="plain" usefile="false" />
            <formatter type="xml" usefile="true" />
            <test name="@{test-suite}" todir="${test.build.results.dir}" />
        </junit>
    </sequential>
</macrodef>

So there are several targets running different suites like this:

<target name="run-xxx-tests" depends="build-tests">
    <exec-tests test-suite="com.mycompany.XxxTestsSuite" />
</target>

<target name="run-yyy-tests" depends="build-tests">
    <exec-tests test-suite="com.mycompany.YyyTestsSuite" />
</target>

Now i also want to run a test suite with Jacoco coverage. So it would be nice to do this:

<target name="run-xxx-tests-with-coverage" depends="build-tests">
    <jacoco:coverage destfile="${test.coverage.unit.file}">
        <exec-tests test-suite="com.mycompany.XxxTestsSuite" />
    </jacoco:coverage>
</target>

However, Jacoco seems to not support macros within coverage tag, as i'm getting error:

Caused by: C:\Users\taavi\projects\cds\build.xml:87: exec-tests is not a valid child of the coverage task
    at org.jacoco.ant.CoverageTask.addTask(CoverageTask.java:68)
    at org.apache.tools.ant.UnknownElement.handleChildren(UnknownElement.java:367)

For now i created another macrodef that is very similar to the "exec-tests" but just adds coverage. It is not critical, but i'm wondering is there any way to still avoid this duplicate "junit" task part?

k6ps


Solution

  • The <jacoco:coverage> task has an enabled attribute that may be useful...

    If set to true coverage data will be collected for the contained task.

    To use enabled, you could make several changes to <exec-tests>:

    • move <jacoco:coverage> into it
    • add an optional coverage.destfile attribute

    How it would look...

    <macrodef name="exec-tests">
        <attribute name="test-suite" />
        <!-- If <test-suite> is called without coverage.destfile, then -->
        <!-- coverage.enabled won't be set to true and coverage info won't -->
        <!-- be collected.  -->
        <attribute name="coverage.destfile" default="" />
        <element name="test-run" implicit="yes" />
        <sequential>
            <local name="coverage.enabled" />
            <condition property="coverage.enabled" value="false" else="true">
                <equals arg1="@{coverage.destfile}" arg2="" />
            </condition>
            <jacoco:coverage enabled="${coverage.enabled}" destfile="@{coverage.destfile}">
                <junit ...>
                ...
                </junit>
            </jacoco:coverage>
        </sequential>
    </macrodef>
    

    Then, each test could specify if coverage information should be collected...

    <exec-tests
        test-suite="com.mycompany.XxxTestsSuite"
        coverage.destfile="${test.coverage.unit.file}" />
    

    In the above example, coverage info will be collected because coverage.destfile is provided.