1

I am trying to get code coverage using Cobertura plugin for Jenkins so I instrument, run tests and then coverage report in my build.xml as follow

<?xml version="1.0" encoding="UTF-8"?>
<project name="CoberturaAndJenkins" default="default" basedir=".">
    <description>Builds, tests, and runs the project CoberturaAndJenkins.</description>
    <import file="nbproject/build-impl.xml"/>

    <property name="lib.dir" value="lib/" />
    <property name="junit.file" value="junit-4.11.jar" />
    <property name="cobertura.dir" value="${lib.dir}/cobertura/" />
    <property name="instrumented.dir" value="/var/lib/jenkins/workspace/CoberturaAndJenkins/instrumented/" />
    <property name="coveragereport.dir" value="build/cobertura/" />
    <property name="classes.dir" value="/var/lib/jenkins/workspace/CoberturaAndJenkins/build/classes/" />
    <property name="reports.xml.dir" value="build/test/results/" /> 

    <!-- Modules that build -->
    <property name="src.dir" value="src/" />
    <property name="test.dir" value="test/" />


    <!-- Define the Cobertura Ant tasks -->
    <path id="cobertura.classpath">
        <fileset dir="${cobertura.dir}">
            <include name="cobertura-2.0.3.jar" />
            <include name="lib/**/*.jar" />
        </fileset>
        <fileset dir="${lib.dir}" >
            <include name="${junit.file}" />
        </fileset>
    </path>

    <taskdef classpathref="cobertura.classpath" resource="tasks.properties" />

    <path id="test.classpath">
        <path refid="cobertura.classpath" />
        <pathelement location="${bin}" />
        <pathelement location="${instrumented.dir}"/>
        <pathelement location="${classes.dir}" />
    </path>

    <!--============= Instrument the classes that JUnit will be testing =============-->
    <target name="instrument">
        <delete file="cobertura.ser"/>
        <delete dir="${instrumented.dir}" />
        <cobertura-instrument todir="${instrumented.dir}" datafile="cobertura.ser" >
            <fileset dir="${classes.dir}">
                <include name="**/*.class" />
                <exclude name="**/*Test.class" />
            </fileset>
        </cobertura-instrument>
    </target>

    <!--======================= JUNIT =======================-->

   <property name="basedir" value="./" />
    <target name="module-test" depends="instrument"> 
        <echo level="info" message="Running test cases..." />

        <junit dir="${basedir}" showoutput="yes" fork="yes" printsummary="yes" failureProperty="test.failed">
            <!--Specify the name of the coverage data file to use.
                    The value specified below is the default.-->
            <sysproperty key="net.sourceforge.cobertura.datafile" file="cobertura.ser" />

            <classpath refid="test.classpath" />

            <formatter type="xml" />
            <batchtest fork="yes" todir="${reports.xml.dir}">
                <fileset dir="${test.dir}">
                    <include name="**/*Test.java" />
                </fileset>
            </batchtest>
        </junit>
    </target>


    <!--===================== COBERTURA REPORT ================================-->
    <target name="coverage-report" depends="module-test">
        <cobertura-report format="xml" destdir="${coveragereport.dir}" datafile="cobertura.ser" >
            <fileset dir="${src.dir}">
                <include name="**/*.java" />
            </fileset>
        </cobertura-report>
        <cobertura-report format="html" destdir="${coveragereport.dir}" datafile="cobertura.ser" >
            <fileset dir="${src.dir}">
                <include name="**/*.java" />
            </fileset>
        </cobertura-report>
    </target>
    <!--================== END OF COBERTURA REPORT ============================-->

</project>

The thing is that when it tries to run the unit tests (which I can run using ant test) it keeps saying

module-test:
Running test cases...
Running coberturaandjenkins.CoberturaAndJenkinsTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
Test coberturaandjenkins.CoberturaAndJenkinsTest FAILED

I have changed, re-changed, re-re-changed the build.xml without any luck for days. I can't get it work. Please, I'd appreciate any help here. It's the first time I'm using ant (and Cobertura)

davidrv87
  • 838
  • 7
  • 16
  • Just to make sure, if you run your test class from an IDE, like Eclipse, does it succeed? – mthmulders Feb 19 '14 at 13:43
  • have you looked in the JUnit report/output folder to see the error? – matt b Feb 19 '14 at 13:45
  • @mthmulders I've already tried that too. The tests run fine in Netbeans (either using `Run > Test File` or `ant test`) – davidrv87 Feb 19 '14 at 14:50
  • @mattb in the output there is this error `java.lang.ClassNotFoundException: coberturaandjenkins.CoberturaAndJenkinsTest`. – davidrv87 Feb 19 '14 at 14:53
  • Debugging the target, it fails at this line and then stops `` – davidrv87 Feb 19 '14 at 15:45
  • @davidrv87 sounds like the code needs to be compiled first – matt b Feb 19 '14 at 15:52
  • Thanks for the answer @mattb but I've added a target to the build.xml to compile the code and the tests before the junit bit is executed. Also added `depends="compile,compile.test"` to the `module-test` target with no luck. Don't know what I'm doing wrong – davidrv87 Feb 19 '14 at 19:58
  • Have you been able to get any clue about the 1 error that is flagged? – mikemil Feb 21 '14 at 21:54
  • Any chance you have a couple copies of cobertura.ser within the build folders? In some cases, you have and then int the instrument task - you use which means it is creating it in the instrumented folder. Might want to make sure all references to the cobertura.ser file are referenced the same way to reference the same folder in all cases. – mikemil Feb 21 '14 at 22:18

1 Answers1

2

Thanks for all your answers guys. After further investigation, I figured out how to make it work. I had to completely re-write the build.xml. Here it is:

<property file="build.properties" />

<path id="cobertura.classpath">
    <fileset dir="${cobertura.dir}">
        <include name="**/*.jar" />
    </fileset>
</path>

<taskdef classpathref="cobertura.classpath" resource="tasks.properties"/>

<target name="init">
    <mkdir dir="${classes.dir}" />
    <mkdir dir="${instrumented.dir}" />
    <mkdir dir="${reports.xml.dir}" />
    <mkdir dir="${reports.html.dir}" />
    <mkdir dir="${coverage.xml.dir}" />
    <mkdir dir="${coverage.summaryxml.dir}" />
    <mkdir dir="${coverage.html.dir}" />
</target>

<target name="compile" depends="init">
    <javac srcdir="${src.dir}" destdir="${classes.dir}" debug="yes" includeantruntime="false">
        <classpath refid="cobertura.classpath" />
    </javac>
    <javac srcdir="${test.src.dir}" destdir="${classes.dir}" debug="yes" includeantruntime="false">
        <classpath refid="cobertura.classpath" />
    </javac>
</target>

<target name="instrument" depends="init,compile">
    <!--
            Remove the coverage data file and any old instrumentation.
    -->
    <delete file="cobertura.ser"/>
    <delete dir="${instrumented.dir}" />

    <!--
            Instrument the application classes, writing the
            instrumented classes into ${build.instrumented.dir}.
    -->
    <cobertura-instrument todir="${instrumented.dir}">
        <!--
                The following line causes instrument to ignore any
                source line containing a reference to log4j, for the
                purposes of coverage reporting.
        -->
        <ignore regex="org.apache.log4j.*" />

        <fileset dir="${classes.dir}">
            <!--
                    Instrument all the application classes, but
                    don't instrument the test classes.
            -->
            <include name="**/*.class" />
            <exclude name="**/*Test.class" />
        </fileset>
    </cobertura-instrument>
</target>

<target name="test" depends="init,compile">
    <junit fork="yes" dir="${basedir}" failureProperty="test.failed">
        <!--
                Note the classpath order: instrumented classes are before the
                original (uninstrumented) classes.  This is important.
        -->
        <classpath location="${instrumented.dir}" />
        <classpath location="${classes.dir}" />

        <!--
                The instrumented classes reference classes used by the
                Cobertura runtime, so Cobertura and its dependencies
                must be on your classpath.
        -->
        <classpath refid="cobertura.classpath" />

        <formatter type="xml" />
        <test name="${testcase}" todir="${reports.xml.dir}" if="testcase" />
        <batchtest todir="${reports.xml.dir}" unless="testcase">
            <fileset dir="${test.src.dir}">
                <include name="**/*Test.java" />
            </fileset>
        </batchtest>
    </junit>

    <!-- JUnit Report in HTML -->
    <junitreport todir="${reports.xml.dir}">
        <fileset dir="${reports.xml.dir}">
            <include name="TEST-*.xml" />
        </fileset>
        <report format="frames" todir="${reports.html.dir}" />
    </junitreport>

</target>

<target name="coverage-check">
    <cobertura-check branchrate="34" totallinerate="100" />
</target>

<target name="coverage-report">
    <!--
            Generate an XML file containing the coverage data using
            the "srcdir" attribute.
    -->
    <cobertura-report srcdir="${src.dir}" destdir="${coverage.xml.dir}" format="xml" />
</target>

<target name="summary-coverage-report">
    <!--
            Generate an summary XML file containing the coverage data using
            the "srcdir" attribute.
    -->
    <cobertura-report srcdir="${src.dir}" destdir="${coverage.summaryxml.dir}" format="summaryXml" />
</target>

<target name="alternate-coverage-report">
    <!--
            Generate a series of HTML files containing the coverage
            data in a user-readable form using nested source filesets.
    -->
    <cobertura-report destdir="${coverage.html.dir}">
        <fileset dir="${src.dir}">
            <include name="**/*.java"/>
        </fileset>
    </cobertura-report>
</target>

<target name="clean" description="Remove all files created by the build/test process.">
    <delete dir="${classes.dir}" />
    <delete dir="${instrumented.dir}" />
    <delete dir="${reports.dir}" />
    <delete file="cobertura.log" />
    <delete file="cobertura.ser" />
</target>

<target name="coverage" depends="compile,instrument,test,coverage-report,summary-coverage-report,alternate-coverage-report" description="Compile, instrument ourself, run the tests and generate JUnit and coverage reports."/>

The properties definition are in the build.properties file referenced at the beginning

davidrv87
  • 838
  • 7
  • 16