如何使用 jacoco 获得外部 java 库的代码覆盖率?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10213464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:03:55  来源:igfitidea点击:

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

javamavenjacoco

提问by Guillaume

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 ?

如果我有一个使用库(一个 jar 文件)的 java 项目,是否有可能获得这个 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 onlynecessary .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.

这背后的想法是,我想找出实际使用的项目所依赖的外部库的比例(比方说 spring、hibernate,或者如果它是一个 Scala 项目,那么它可能是 Scala jars,为什么不)。我什至想象我可以尝试列出它们并将它们重新捆绑在一个 jar 中,该 jar包含必要的 .class 文件(例如,使用 apache felix 之类的插件)以获得尽可能小的 jar。我不确定我是否真的想这样做,我知道出于多种原因这可能是一个坏主意,但我认为这是一种实验。

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 :

我找不到怎么做,jacoco 只报告直接在我的项目中的类文件的覆盖范围。也许我做错了什么,我正在使用这样的 Maven 插件:

        <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 :

在 oers 的回答后编辑:

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 !

我发现了如何使用 ant 和 antrun-plugin,虽然它非常复杂,但我在使用 antrun 插件版本时遇到了很多麻烦(无法使最新版本工作,即使是基本任务),我真的很想坚持 Maven。如果有人知道如何使用 je jacoco maven 插件而不是 ant 做等效的事情,我很感兴趣!

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/) :

ant 的部分解决方案:实际上 jacoco.exec 文件已经包含对我的外部 jar 类的引用;因此,应该告诉报告任务考虑这些 jar,而不是我认为的运行时阶段。这是我使用的 maven 配置(我在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>

回答by oers

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.

如果您可以执行 ant,我建议您查看报告任务

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

回答by Hynek Mlnarik

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:

尽管这个问题很老,但它似乎仍然相关。如果外部库是 Maven 项目,您可以转到库源目录并从那里请求先前使用您的测试套件获得的 JaCoCo 报告:

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.

您在 ${project}/target/site/jacoco 目录中获取报告。