How can I get code coverage of an external java library with jacoco?

12,024

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.

Share:
12,024
Guillaume
Author by

Guillaume

Updated on June 06, 2022

Comments

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