带有Ant脚本的Cobertura:xml / html覆盖率报告始终显示0%的覆盖范围

时间:2010-10-19 08:46:07

标签: ant junit code-coverage cobertura

我试图在我的蚂蚁脚本中运行Cobertura。一切都是成功的(源代码构建,junit测试,cobertura报告(xml / html);但在html报告中,代码覆盖率始终为0%......

Ant脚本: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="**/*Test.class" />
        </fileset>

    </cobertura-instrument>

</target>

Ant脚本: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脚本: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>

4 个答案:

答案 0 :(得分:4)

这是Cobertura FAQ所说的

当我生成报道报告时,为什么它们总是在任何地方显示0%的覆盖率?

Cobertura在生成报告时可能使用了错误的.ser文件。当您修改课程时,Cobertura会生成一个.ser文件,其中包含有关每个课程的基本信息。当您的测试运行时,Cobertura会为此相同的数据文件添加其他信息。如果检测类在运行时找不到数据文件,那么它们将创建一个新文件。在检测,运行和生成报告时,使用相同的cobertura.ser文件非常重要。

执行此操作的最佳方法是在运行测试时指定数据文件的位置。您应该将-Dnet.sourceforge.cobertura.datafile=${basedir}/cobertura.ser sysproperty传递给JUnit任务。

另一个常见问题是cobertura.ser文件已删除,但之前已检测的类也未删除。每次删除coverage数据文件时,都应删除所有已检测的类。

答案 1 :(得分:1)

好的,我发现了问题。确定有这个:

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

检测类必须在原始(未经检测)类之前。

答案 2 :(得分:1)

我尝试过类似的方式。我还在实际源代码之前使用了检测代码,但是我在报告文件中得到了0%。

<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>

令人惊讶的是,生成的报告显示总覆盖率为2%,但摘要文件显示0%覆盖率。     旧的cobertura任务显示8%的覆盖率。我完全糊涂了:(

答案 3 :(得分:0)

可能它并不适用于所有人,但我遇到的类似问题是所有课程的覆盖率均为0。 在我的案例中有2个问题

1)从PATH读取错误的jdk 1.8版本。我更新了PATH以阅读1.6 jdk 2)它最初使用的是cobertura的1.8版本。我运行了构建,它将生成覆盖率报告,但所有类始终为0%。我更新了javac目标以包含 debug="true" debuglevel="vars,lines,source"参考:cobertura 0 coverage

然后再次运行构建,看到运行测试时出现错误,并将其追溯到cobertura 1.8版本的问题。

所以,我升级了

  1. Cobertura 1.9.4
  2. asm 3.1 from 2.2.1
  3. asm-tree 3.1
  4. 其他依赖性
     1. jakarta-oro 2.0.8
     2. log4j-1.2.9

    之后再次执行任务,报告也没问题。