开发者

Cobertura with Ant Script : xml/html coverage report always show 0% coverage everywhere

开发者 https://www.devze.com 2023-01-20 08:19 出处:网络
I tried to get Cobertura running inside my ant script. All is successfull (source code building, junit tests, cobertura reports (xml / html); but in html reports, the code coverage is always at 0% ...

I tried to get Cobertura running inside my ant script. All is successfull (source code building, junit tests, cobertura reports (xml / html); but in html reports, the code coverage is always at 0% ...

Ant Script : make-instrument

<!-- Make instrument for Cobertura engine -->
<target name="make-instrument">

    <!-- Remove the coverage data file and any old instrumentation. -->
    <delete file="${cobertura.ser}" />

    <!-- Instrument the application classes, writing the instrumented classes into ${build.instrumented.dir}. -->
    <cobertura-instrument todir="${report.cobertura.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="${webcontent.dir}/WEB-INF/classes">
            <!-- Instrument all the application classes, but don't instrument the test classes. -->
            <include name="**/*.class" />
            <exclude name开发者_JAVA百科="**/*Test.class" />
        </fileset>

    </cobertura-instrument>

</target>

Ant Script : make-instrument

<target name="install-cobertura" if="is-hudson-env">        
    <path id="cobertura.classpath">
        <fileset dir="${user.home.sharehunter.dir}/cobertura-${cobertura.rev}">
            <include name="**/cobertura.jar" />
            <include name="**/*.jar" />
        </fileset>
    </path>
    <taskdef resource="tasks.properties" classpathref="cobertura.classpath" />
</target>

Ant Script : junit

<target name="run-tests" depends="make-instrument">

    <path id="classpath.test">
        <path path="${webcontent.dir}/WEB-INF/classes" />
        <pathelement location="${webcontent.dir}/WEB-INF/classes" />
        <fileset dir="${lib.dir}" includes="**/*.jar" />
        <path location="${webcontent.dir}/WEB-INF/classes" />
        <path location="${webcontent.dir}/WEB-INF" />
        <path location="${webcontent.dir}" />
    </path>

    <junit fork="yes" failureProperty="test.failed">

        <classpath refid="classpath.test" />

        <classpath location="${user.home.dir}/junit-${junit.rev}.jar" />

        <!-- 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}" />

        <!-- Note the classpath order: instrumented classes are before the original (uninstrumented) classes. -->
        <classpath location="${report.cobertura.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" />

        <!-- Generate xml files for each junit tests runs -->
        <formatter type="xml" />
        <batchtest todir="${report.junit.dir}">
            <fileset dir="${webcontent.dir}/WEB-INF/classes">
                <include name="**/*Test.class" />
            </fileset>
        </batchtest>

    </junit>

    <!-- Generate Cobertura xml file containing the coverage data -->
    <cobertura-report format="xml" srcdir="${src.main.java.dir}" destdir="${report.cobertura.dir}" datafile="${cobertura.ser}" />

    <!-- Generate Cobertura html file report  containing the coverage data -->
    <cobertura-report format="html" srcdir="${src.main.java.dir}" destdir="${report.cobertura.dir}" datafile="${cobertura.ser}" />

</target>


This is what Cobertura FAQ Says

When I generate coverage reports, why do they always show 0% coverage everywhere?

Cobertura is probably using the wrong .ser file when generating the reports. When you instrument your classes, Cobertura generates a .ser file containing basic information about each class. As your tests run, Cobertura adds additional information to this same data file. If the instrumented classes can not find the data file when running then they will create a new one. It is important that you use the same cobertura.ser file when instrumenting, running, and generating reports.

The best way to do this is to specify the location of the data file when running your tests. You should pass the -Dnet.sourceforge.cobertura.datafile=${basedir}/cobertura.ser sysproperty to the JUnit task.

Another common problem is that the cobertura.ser file is deleted, but the previously instrumented classes are not also deleted. Any time you delete your coverage data file you should also deleted all instrumented classes.


Ok I found the problem. To be sure have this :

    <!--
    Note the classpath order: instrumented classes are before the
    original (uninstrumented) classes.  This is important.
-->
<classpath location="${instrumented.dir}" />
<classpath location="${classes.dir}" />

Instrumented classes must are before the original (uninstrumented) classes.


I tried similar way. I also used instrumented code before actual source code, but I am getting 0 % in the report file.

<macrodef name="coberturaTestMacro">
        <attribute name="moduleName" />
        <attribute name="classpath.module" />
        <attribute name="classpath.junit" />
        <attribute name="failOnCoverageFall" />
        <attribute name="fileCoberturaData"/>
        <sequential>

            <path id="classpathCobertura">
                <fileset dir="${homeCobertura}">
                    <include name="cobertura.jar" />
                    <include name="lib/**/*.jar" />
                </fileset>
            </path>
            <taskdef classpathref="classpathCobertura" resource="tasks.properties" />
            <property name="cob.instrumented.dir" value="target/cobertura/instrumented" />

            <delete dir="target/cobertura" />

            <cobertura-instrument todir="${cob.instrumented.dir}" datafile="@{fileCoberturaData}" >
                <fileset dir="target/classes">
                    <include name="**/*.class" />
                </fileset>
            </cobertura-instrument>

            <delete dir="target/reports/test" />
            <mkdir dir="target/cobertura/reports" />
            <junit printsummary="false" failureproperty="junit.failure"
                        maxmemory="512m" fork="true" forkmode="perTest">
                <jvmarg value="-Djava.awt.headless=true" />
                <classpath location="${homeCobertura}/cobertura.jar" />
                <classpath location="${cob.instrumented.dir}" />
                <classpath>
                    <path refid="@{classpath.module}" />
                    <path refid="@{classpath.junit}" />
                </classpath>
                <classpath path="target/test-classes" />
                <batchtest todir="target/cobertura/reports/">
                    <fileset dir="src/test/java">
                        <include name="**/*Test.java" />
                    </fileset>
                </batchtest>
            </junit>

            <cobertura-report srcdir="src/main/java" destdir="target/cobertura/reports/" />

            <echo message="${line.separator}" />
            <echo message="COVERAGE: @{moduleName} module..." />
            <echo message="${line.separator}" />

            <if>
                <available file="target/cobertura/@{moduleName}-cobertura.properties" />
                <then>
                    <var name="total.line-rate" file="target/cobertura/@{moduleName}-cobertura.properties" />
                    <cobertura-check haltonfailure="@{failOnCoverageFall}"
                        datafile="@{fileCoberturaData}" totallinerate="${total.line-rate}" />
                </then>
            </if>

            <delete file="${dirBuild}/coverage-summary.properties" />
            <cobertura-report datafile="@{fileCoberturaData}" destdir="target/cobertura/" format="summaryXml" />
            <var name="total.line-rate" file="target/cobertura/coverage-summary.properties" />
            <echo message="Total line coverage: ${total.line-rate}%" />

            <propertyfile file="target/cobertura//@{moduleName}-cobertura.properties">
                <entry key="total.line-rate" value="${total.line-rate}" type="int" />
            </propertyfile>

        </sequential>
    </macrodef>

The surprising thing is that the generated report says total 2% coverage, but summary file says 0% coverage. Where old cobertura task shows 8% coverage. I am totally confused :(


Probably it is not applicable to everybody but I had the similar issue where coverage was 0 for all classes. There were 2 issues in my case

1) it was reading wrong jdk version 1.8 off of PATH. I updated PATH to read 1.6 jdk.
2) it was initially using version 1.8 of cobertura. I ran the build and it would generate coverage report but all the classes were 0% always. I updated the javac target to include debug="true" debuglevel="vars,lines,source" reference: cobertura 0 coverage

Then ran the build again and saw that the there was an error when running tests and traced that back to an issue with version 1.8 of cobertura.

So, I upgraded

  1. Cobertura 1.9.4
  2. asm 3.1 from 2.2.1
  3. asm-tree 3.1

other dependencies
1. jakarta-oro 2.0.8
2. log4j-1.2.9

After that ran the task again and the reports were alright.

0

精彩评论

暂无评论...
验证码 换一张
取 消