【问题标题】:How would I add an annotation to exclude a method from a jacoco code coverage report?如何添加注释以从 jacoco 代码覆盖率报告中排除方法?
【发布时间】:2018-05-29 05:11:29
【问题描述】:

我有一些 Java 代码,我想从代码覆盖范围中排除。我该怎么做?我希望能够添加注释。有没有办法配置或扩展 jacoco(在 gradle 中使用)来使用它?

例子:

public class Something
{
    @ExcludeFromCodeCoverage
    public void someMethod() {}
}

【问题讨论】:

    标签: java gradle junit code-coverage jacoco


    【解决方案1】:

    由于没有直接的答案,所以做了一些研究并遇到了这个 PR。

    https://github.com/jacoco/jacoco/pull/822/files

      private static boolean matches(final String annotation) {
        final String name = annotation
                .substring(Math.max(annotation.lastIndexOf('/'),
                        annotation.lastIndexOf('$')) + 1);
        return name.contains("Generated")
      }
    

    您可以创建名称包含“已生成”的任何注释。我在我的代码库中创建了以下内容,以排除方法包含在 Jacoco 报告中。

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface ExcludeFromJacocoGeneratedReport {}
    

    在您的方法中使用此注解使其免于覆盖,如下所示。

    public class Something
    {
        @ExcludeFromJacocoGeneratedReport
        public void someMethod() {}
    }
    

    【讨论】:

    • 你试过这个并确认它有效吗?
    • 是的@DonRhummy。我可以看到在 Sonarcloud 分析中跳过了带有注释的方法
    • 这是否需要特定的声纳扫描仪,因为我可以看到它对我不起作用,但该功能在报告中显示为未发现
    • 也许你应该更新 Jacoco 插件版本
    • @MohamedAneesA 我找到了解决方法:Intellij 代码覆盖(jacoco 的包装器)无法正常工作。但是运行 raw jacoco 就可以了。
    【解决方案2】:

    在 JaCoCo 的 0.8.2 版本中添加了新功能,它过滤掉了带有 @Generated 注释的类和方法。有关详细信息,请参阅以下文档:

    保留策略为 runtime 或 class 且简单名称为 Generated 的类和方法在生成报告期间被过滤掉 (GitHub #731)。

    JaCoCo 0.8.2 Release Notes

    【讨论】:

    • 这包括您在自己的应用程序中定义的注释,称为Generated
    【解决方案3】:

    我有一些 Java 代码,我想从代码覆盖范围中排除。我该怎么做?我希望能够添加注释。有没有办法配置或扩展 jacoco(在 gradle 中使用)来使用它?

    截至今天,最新发布的 JaCoCo (0.7.9) 版本中没有此类功能。只能排除整个类。

    在页面https://github.com/jacoco/jacoco/wiki/FilteringOptions#annotation-based-filtering(专门为开发人员提供)上,这被记录为未来版本的想法。

    JaCoCo 官方文档包含有关如何获取最新未发布版本的信息以及下一版本的未发布更改列表 - http://www.jacoco.org/jacoco/trunk/doc/changes.html ,其中包括各种过滤器,其中过滤生成的方法由 Lombok 和 Groovy 分别用注释 lombok.Generatedgroovy.transform.Generated 标记。您可能会滥用此功能,但出于多种原因,我不建议您这样做。

    【讨论】:

    • +1,但是......这样一个注释的合法用途是什么?我在任何地方都找不到这样的例子,我的感觉是覆盖工具中的这个功能只会被误用和滥用。如果源代码中存在一个方法并且不为空,那么我认为它应该在覆盖率分析中考虑,即使源代码是由某些工具生成的。毕竟,该方法应该会对应用程序/系统功能做出一些贡献,对吧?如果是这样,为什么不测试呢?
    • @Rogério - “静态”辅助类中的私有构造函数 - 我不认为使用反射来强制构造函数执行是正确的方法......
    • @CptBartender 当然通过Reflection调用私有构造函数不是解决方案...正确的解决方案是代码覆盖工具自动过滤掉它们; JaCoCo 已经在为一个私有的空构造函数做这件事了。
    • @Rogério 我不想介绍用于 Q&D 测试的 main() 方法或如何使用该类的示例。这天真地看起来像是一个合法的用例。
    • JaCoCo 最新版本支持这个功能吗?
    【解决方案4】:

    Tl;dr

    使用来自Lombok 的注解@lombok.Generated

    说明

    Jacoco 与Lombok 集成。默认情况下,Lombok 生成的代码不包括在 Jacoco 覆盖范围内(请参阅Release 0.8.0 in Jacoco changelog)。你可以在你的方法中滥用lombok.Generated,因为它被排除在覆盖率报告之外。

    【讨论】:

    • Lombok 使用未记录的、非官方的类,这些类不能保证在每个 java 运行时中都有。 (强烈建议不要使用)
    • 请务必注意,这是一种 hack 解决方法。强烈建议避免。
    • 如何“扩展”@Generated 注释以便能够将其重命名为类似 OP 建议的名称:@ExcludeFromCodeCoverage
    • 我很确定你必须为 JaCoCo 打补丁才能这样做。
    【解决方案5】:

    您可以在项目的根目录中将lombok.addLombokGeneratedAnnotation = true 设置为lombok.config。之后,Jacoco 将忽略所有 Lombok 生成的代码。

    在 Project Lombok 文档中查看更多信息:https://projectlombok.org/features/configuration

    【讨论】:

    • Lombok 使用未记录的、非官方的类,这些类不能保证在每个 java 运行时中都有。 (强烈建议不要使用)
    • @DonRhummy 我不知道我是否正确理解了您的评论,Lombok 是一个编译时依赖项/插件,应用程序将附带编译后的代码,其中不应包含与 lombok 相关的任何内容。如果我遗漏了什么,请告诉我。
    【解决方案6】:

    按照@mohamed-anees-a 方法,我得到了这个 kotlin 版本:

    @Retention(AnnotationRetention.RUNTIME)
    @Target(AnnotationTarget.FUNCTION)
    annotation class ExcludeFromJacocoGeneratedReport
    

    【讨论】:

      猜你喜欢
      • 2018-07-27
      • 1970-01-01
      • 1970-01-01
      • 2011-11-26
      • 1970-01-01
      • 2019-04-10
      • 2015-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多