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