Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jacoco - Zero Percent Coverage

Tags:

java

jacoco

I am trying to integrate jacoco to our ant build and evaluate it with a simple test project.

The compilation and the other output looks promising, but when I look at the coverage it is always zero.

package alg;

public class SpecialAlgorithm {
    public SpecialAlgorithm() {}

    public int uncoveredMethod(int i) {
        return i * i;
    }

    public int sum(int i, int j) {
        return i + j;
    }   
}

Testcase:

package alg;

import static org.junit.Assert.assertEquals;
import org.junit.Test;
import alg.SpecialAlgorithm;

public class SpecialAlgorithmTest {
    @Test
    public void testSum() {
        SpecialAlgorithm alg = new SpecialAlgorithm();
        int sum = alg.sum(1, 2);
        assertEquals(3, sum);
    }
}

Ant script:

<project xmlns:jacoco="antlib:org.jacoco.ant" name="Code Coverage with JaCoCo"
    default="rebuild">
    <property name="src.dir" location="../java" />
    <property name="test.dir" location="../../test/java" />
    <property name="result.dir" location="c:/temp/jacoco/target" />
    <property name="result.classes.dir" location="${result.dir}/classes" />
    <property name="result.report.dir" location="${result.dir}/site/jacoco" />
    <property name="result.exec.file" location="${result.dir}/jacoco.exec" />
    <!-- Step 1: Import JaCoCo Ant tasks -->
    <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
        <classpath path="../../../lib/jacocoant.jar" />
    </taskdef>
    <target name="clean">
        <delete dir="${result.dir}" />
        <mkdir dir="${result.dir}" />
        <mkdir dir="${result.dir}/site/jacoco/" />
    </target>
    <target name="compile" depends="clean">
        <mkdir dir="${result.classes.dir}" />
        <javac srcdir="${src.dir}" destdir="${result.classes.dir}"
            debug="true" includeantruntime="false">
            <classpath>
                <pathelement location="${result.classes.dir}" />
            </classpath>
        </javac>
    </target>
    <target name="test" depends="compile">
        <taskdef name="junit"
            classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask">
            <classpath>
                <pathelement location="../../../lib/junit.jar" />
                <pathelement location="../../../bin" />
                <pathelement location="${result.classes.dir}" />
            </classpath>
        </taskdef>

        <jacoco:coverage destfile="${result.dir}/jacoco.exec"
            xmlns:jacoco="antlib:org.jacoco.ant">
            <junit fork="yes" forkmode="once" dir="." failureProperty="test.failed">
                <classpath>
                    <pathelement location="../../../lib/junit.jar" />
                    <pathelement location="../../../bin" />
                    <pathelement location="${result.classes.dir}" />
                </classpath>

                <formatter type="xml" />
                <batchtest todir="${result.report.dir}">
                    <fileset dir="${test.dir}"/>
                </batchtest>
            </junit>
        </jacoco:coverage>
        <!-- Step 3: Create coverage report -->
        <jacoco:report>
            <!-- This task needs the collected execution data and ... -->
            <executiondata>
                <file file="${result.exec.file}" />
            </executiondata>
            <!-- the class files and optional source files ... -->
            <structure name="JaCoCo Ant Example">
                <classfiles>
                    <fileset dir="../../../bin" />
                </classfiles>
                <sourcefiles encoding="UTF-8">
                    <fileset dir="${src.dir}" />
                </sourcefiles>
            </structure>
            <!-- to produce reports in different formats. -->
            <html destdir="${result.report.dir}" />
            <csv destfile="${result.report.dir}/report.csv" />
            <xml destfile="${result.report.dir}/report.xml" />
        </jacoco:report>
    </target>
    <target name="rebuild" depends="test" />
</project>

UPDATE: After upgrading to the newer version I get a warning which may indicate what my mistake is.

Console output:

Buildfile: JacocoEvaluation\src\main\resources\coverage.xml
clean:
   [delete] Deleting directory c:\temp\jacoco\target
    [mkdir] Created dir: c:\temp\jacoco\target
    [mkdir] Created dir: c:\temp\jacoco\target\site\jacoco
compile:
    [mkdir] Created dir: c:\temp\jacoco\target\classes
    [javac] Compiling 1 source file to c:\temp\jacoco\target\classes
test:
[jacoco:coverage] Enhancing junit with coverage
[jacoco:report] Loading execution data file c:\temp\jacoco\target\jacoco.exec
[jacoco:report] Writing bundle 'JaCoCo Ant Example' with 1 classes
[jacoco:report] Classes in bundle 'JaCoCo Ant Example' do no match with execution data. For report generation the same class files must be used as at runtime.
[jacoco:report] Execution data for class alg/SpecialAlgorithm does not match.
rebuild:
BUILD SUCCESSFUL
Total time: 1 second

The directory structure (like maven):

main/java/ Class to Test test/java/ Testcase

Any ideas what I am doing wrong? The plugin works fine.

UPDATE: Works now. I had the wrong directory referenced in the report structure. The newer version of jacoco printed a warning which helped to spot the problem.

like image 901
mkuff Avatar asked Apr 29 '14 13:04

mkuff


People also ask

Why does JaCoCo not show coverage?

Why does the coverage report not show highlighted source code? Make sure the following prerequisites are fulfilled to get source code highlighting in JaCoCo coverage reports: Class files must be compiled with debug information to contain line numbers. Source files must be properly supplied at report generation time.

How does JaCoCo calculate coverage?

To calculate the code coverage percentage, simply use the following formula: Code Coverage Percentage = (Number of lines of code executed by a testing algorithm/Total number of lines of code in a system component) * 100. 16) Where is the JaCoCo report generated Gradle?

What is complexity coverage in JaCoCo?

JaCoCo calculates cyclomatic complexity of a method with the following equivalent equation based on the number of branches (B) and the number of decision points (D): v(G) = B - D + 1. Based on the coverage status of each branch JaCoCo also calculates covered and missed complexity for each method.

How do I increase my JaCoCo coverage?

For the code coverage to increase , one would need to run the tests with the coverage enabled and then view the report generated locally to see the areas covered by jacoco during its coverage parse, then from these one would see the methods (per class) that needs to be covered from the view of the jacoco agent.


2 Answers

I had the wrong directory referenced in the report structure. The newer version of jacoco printed a warning which helped to spot the problem. Corrected my script in the original post. Maybe it helps someone sometime.

like image 121
mkuff Avatar answered Sep 25 '22 18:09

mkuff


It's wierd. In my case, I used Java JDK 1.8.0_45 to "gradle clean build" and "gradle jacocoTestReport". Got the same error as Oscar mentioned above with Gradle.

jacocoXX.exec file was at the correct location.

Ran "gradle clean build" when JDK was 1.8.0_45, then ran "gradle jacocoTestReport" with JDK 1.7.0_40 -- It worked like a charm.

One other solution is: If you want to use JDK 1.8.0_45 (i.e. Java8) for both build and jacocoTestReport tasks, then call like: gradle -x compileJava -x test -x classes -x testClasses jacocoTestReport (then the error doesn't come).

like image 37
AKS Avatar answered Sep 23 '22 18:09

AKS