Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JaCoCo does not show the source files in the HTML coverage report for multi projects

I'm using PDE and in my build.xml I compile my code and try to create a coverage report using JaCoCo and JUnit. I noticed that it does now show the sourcefile, even though I added sourcefiles section in the structure section of jacoco:report. In order to debug it (because it does not prints any errors), I tried to run it locally:

java -jar jacoco/jacococli.jar report /buildFiles/coverage/jacoco.exec --classfiles /buildFiles/plugins/com.gandu.da.util.test/bin/com/gandu/da/util/test/AllTests.class --sourcefiles /buildFiles/plugins/com.gandu.da.util.test/src/com/gandu/da/util/test/AllTests.java --html html_report

But it still does not show the sourcecode in the html file. In the official JaCoCo FAQ I see:

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. I.e. specified source folders must be the direct parent of the folders that define the Java packages.

I compiled the code with -g flag to get all the information - it didn't work. Also I believe that I do supply the src/bin files as expected so I'm not sure why it does not work. How to make it work?

EDIT: I had to provide the src directory:

java -jar jacoco/jacococli.jar report /buildFiles/coverage/jacoco.exec --classfiles /buildFiles/plugins/com.gandu.da.util.test/bin/com/gandu/da/util/test/AllTests.class --sourcefiles /buildFiles/plugins/com.gandu.da.util.test/src
# WORKED!

Now I want to fix the issue with my build.xml. The code:

<jacoco:report>
    <executiondata>
        <file file="${coverage.file}"/>
    </executiondata>
    <structure name="Coverage Report">
        <classfiles>
            <fileset dir="${buildDirectory}/plugins/com.gandu.da.util.test/bin">
                <include name="**/*.class" />
            </fileset>
        </classfiles>
        <sourcefiles encoding="UTF-8">
            <fileset dir="${buildDirectory}/plugins/com.gandu.da.util.test/src">
                <include name="**/*.java" />
            </fileset>
        </sourcefiles>
    </structure>
    
    <html destdir="${coverage.html}"/>
</jacoco:report>

This code worked and it provided the coverage report with the source files. But as you can see I had to hardcoded only one package (com.gandu.da.util.test). I want to create a coverage report from all the packages that:

  • src: ${buildDirectory}/plugins/com.gandu*/src.
  • bin: ${buildDirectory}/plugins/com.gandu*/bin.

So I tried:

<jacoco:report>
    <executiondata>
        <file file="${coverage.file}"/>
    </executiondata>
    <structure name="Coverage Report">
        <classfiles>
            <fileset dir="${buildDirectory}/plugins/com.gandu.*/bin">
                <include name="**/*.class" />
            </fileset>
        </classfiles>
        <sourcefiles encoding="UTF-8">
            <fileset dir="${buildDirectory}/plugins/com.gandu.*/src">
                <include name="**/*.java" />
            </fileset>
        </sourcefiles>
    </structure>
    
    <html destdir="${coverage.html}"/>
</jacoco:report>

But it didn't work because the path (with the star) does not exist. It makes sense because dir expects to get one path. So I figured that <foreach> might help here but after reading the docs, I could not figure a way to use it. The above code is what I need. I hope to hear a suggestion on how to solve this.

One more note since it's important: the structure of source and class files:

  • source files are located under ${buildDirectory}/plugins/com.gandu*/src.
  • class files are located under: ${buildDirectory}/plugins/com.gandu*/bin.

I also tried to insert ${buildDirectory}/plugins in dir of both <classfiles> and <sourcefiles> but it didn't work. It does create the coverage report but it does not show the source files. I guess I need to provide the src dir of each package.

So I thought to use <foreach> to insert each package into the structure. I might need to use jacoco:merge to merge them, but I'm not sure.

Also tried includes="**/usr/** and includes="**/bin/**.

I also have a few different ant version I could use here. might help? Also, maybe I could "hardcode" the plugins somehow and "merge" the reports?

EDIT: It looked like it worked when you provide multi plugins like so:

<jacoco:report>
    <!--  This task needs the collected execution data and ...  -->
    <executiondata>
        <file file="${coverage.metadata.file}"/>
    </executiondata>
    <!--  the class files and optional source files ...  -->
    <structure name="JaCoCo Coverage Report">
        <classfiles>
            <fileset dir="${buildDirectory}/plugins/com.gandu.da.util.mangager.test/@dot">
                 <include name="**/*.class" />
            </fileset>
            <fileset dir="${buildDirectory}/plugins/com.gandu.da.util.alltests/@dot">
                 <include name="**/*.class" />
            </fileset>
        </classfiles>
        <sourcefiles encoding="UTF-8">
            <fileset dir="${buildDirectory}/plugins/com.gandu.da.util.mangager.test/src">
                <include name="**/*.java" />
            </fileset>
            <fileset dir="${buildDirectory}/plugins/com.gandu.da.util.alltests/src">
                <include name="**/*.java" />
            </fileset>
        </sourcefiles>
    </structure>
    
    <html destdir="${coverage.html.dir}"/>
    <csv destfile="${coverage.csv.file}"/>
    <xml destfile="${coverage.xml.file}"/>
</jacoco:report>

Is it possible to maybe put all the wanted names (like com.gandu.da.util.alltests) into a file, read them one by one, and run for (or foreach) on them and add them as fileset maybe (after you append each one with the path)?

like image 979
vesii Avatar asked Aug 30 '21 16:08

vesii


People also ask

How do I get JaCoCo HTML report?

For generating JaCoCo reports only run the maven build with profile jacoco-generate-report as it is shown in the example above. After the command was executed, in directory target/jacoco-report you can find reports in HTML and XML formats.

How do I exclude generated sources from JaCoCo?

Starting from JaCoCo 0.8. 2, we can exclude classes and methods by annotating them with a custom annotation with the following properties: The name of the annotation should include Generated. The retention policy of annotation should be runtime or class.

What files do we need to create JaCoCo report?

Supported formats are HTML, XML and CSV. Defaults to all formats if no values are given. Default value is: HTML,XML,CSV . A list of class files to include in the report.

What is difference between JaCoCo and SonarQube?

SonarQube has a broader approval, being mentioned in 163 company stacks & 271 developers stacks; compared to JaCoCo, which is listed in 5 company stacks and 11 developer stacks.


1 Answers

The issue is not meeting one of the declared preconditions:

specified source folders must be the direct parent of the folders that define the Java packages

--sourcefiles /buildFiles/plugins/com.gandu.da.util.test/src

Gradle might be a whole lot more script-able than the CLI or Maven is.

like image 77
Martin Zeitler Avatar answered Oct 12 '22 00:10

Martin Zeitler