How can I get code coverage of an external java library with jacoco?
Solution 1
You need to give the report goal the classes of the library you want to analyze. Unfortunatly I can't find a documentation on that. The official docu is ... hm ... sparse
IF you can execute ant, I'd suggest looking at the report task.
<jacoco:report>
<executiondata>
<file file="jacoco.exec"/>
</executiondata>
<structure name="Example Project">
<classfiles>
<fileset dir="classes"/> <!-- HERE THE CLASSES FROM YOUR LIB -->
</classfiles>
<sourcefiles encoding="UTF-8">
<fileset dir="src"/> <!-- HERE THE SORUCESFROM YOUR LIB -->
</sourcefiles>
</structure>
<html destdir="report"/>
</jacoco:report>
Solution 2
Even though this question is old, it still seems relevant. If the external library is a Maven project, you can go to the library source directory and request JaCoCo report obtained previously with your testsuite from within there:
mvn org.jacoco:jacoco-maven-plugin:0.7.8:report -Djacoco.dataFile=/path/to/jacoco.exec
You obtain the report in ${project}/target/site/jacoco directory.
Guillaume
Updated on June 06, 2022Comments
-
Guillaume almost 2 years
If I have a java project that uses a library (a jar file), is it possible to get the code coverage of classes inside this jar ?
The idea behind this is that I would like to find out what proportion of the external libraries the project relies on (let's say spring, hibernate, or it could be the scala jars if it was a scala project, why not) are actually used. I even imagine that I could try to list them and rebundle them in a single jar that would contain only necessary .class files (with a plugin like apache felix, for example) to get the smallest possible jar. I'm not sure I really want to do this, I'm aware it is probably a bad idea for a number of reasons, but I think of it as an experimentation.
I can't find how to do it, jacoco reports only coverage for the class files directly inside my project. Maybe I'm doing something wrong, I'm using the maven plugin like this :
<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.5.6.201201232323</version> <configuration> <destfile>${basedir}/target/coverage-reports/jacoco-unit.exec</destfile> <datafile>${basedir}/target/coverage-reports/jacoco-unit.exec</datafile> <includes> <include>**</include> </includes> </configuration> <executions> <execution> <id>jacoco-initialize</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>jacoco-site</id> <phase>package</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin>
I've tried changing the include tag, but the only effect is restricting the default which includes only the class files directly inside my project.
Thanks in advance !
Edit after oers' answer :
I found out how to do it with ant and antrun-plugin, though it is very complicated, I had much trouble with antrun plugin versions (unable to make a recent version work, even for a basic task) and I'd really like to stick to Maven. If someone knows how to do the equivalent with je jacoco maven plugin instead of ant, I'm interested !
Partial solution with ant : actually the jacoco.exec file already contained references to the classes of my external jars ; therefore it is the report task that should be told to take account of these jar, and not the runtime phase as I thought. Here is the maven configuration I used (I found help on http://intellectualcramps.wordpress.com/2012/03/22/jacoco-tycho-and-coverage-reports/ ) :
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <!--<version>1.7</version>--> <dependencies> <dependency> <groupId>org.jacoco</groupId> <artifactId>org.jacoco.ant</artifactId> <version>0.5.6.201201232323</version> </dependency> <dependency> <groupId>ant-contrib</groupId> <artifactId>ant-contrib</artifactId> <version>20020829</version> </dependency> </dependencies> <executions> <execution> <id>jacoco-report</id> <phase>package</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <taskdef name="jacoco-report" classname="org.jacoco.ant.ReportTask" classpathref="maven.plugin.classpath" /> <taskdef classpathref="maven.runtime.classpath" resource="net/sf/antcontrib/antcontrib.properties" /> <available file="${project.basedir}/target/jacoco.exec" property="jacoco.exec.file.exists" /> <echo message="${project.basedir}/target/jacoco.exec" /> <if> <equals arg1="${jacoco.exec.file.exists}" arg2="true" /> <then> <echo message="Executing jacoco report" /> <trycatch> <try> <jacoco-report> <executiondata> <file file="${project.basedir}/target/jacoco.exec" /> </executiondata> <structure name="Minerva"> <classfiles> <fileset dir="target/classes" /> <fileset dir="C:/Data/dev/m2Repository/com/groupama/framework/crypt/fwk-cryptage/1.0/"> <include name="**/*.jar"/> </fileset> </classfiles> <sourcefiles encoding="UTF-8"> <fileset dir="src/main/java" /> </sourcefiles> </structure> <html destdir="${project.basedir}/target/jacoco/report" /> <xml destfile="${project.basedir}/target/jacoco/report/jacoco.xml"/> </jacoco-report> </try> <catch> <echo>skipping</echo> </catch> </trycatch> </then> <else> <echo message="No jacoco.exec file found." /> </else> </if> </tasks> </configuration> </execution> </executions> </plugin>