使用 Jacoco 从 Sonar 的条件覆盖范围中排除 groovy slf4j 日志记录

2024-04-26

我们使用 SonarQube 5.1 和 Jacoco maven 插件 0.7.4,以及我们所有的 slf4j 日志记录语句,例如log.debug('Something happened')表明仅覆盖了 2 个分支中的 1 个。我明白这是因为 slf4j 内部做了一个if debug,这很好,但我们不希望这影响我们的数据。我们对测试 slf4j 不感兴趣,并且我们不想针对不同的日志记录级别多次运行每个测试。

那么,我们如何告诉 Sonar 和/或 Jacoco 将这些线路排除在覆盖范围之外?它们都有可配置的文件排除,但据我所知,这些仅用于从覆盖范围中排除您自己的类(使用目标目录),而不是导入的库。我尝试添加groovy.util.logging.*'无论如何,它都被列入排除列表,但它没有做任何事情。

logger.isDebugEnabled() 正在杀死我的代码覆盖率。我打算在运行 cobertura 时排除它 https://stackoverflow.com/questions/22047523/logger-isdebugenabled-is-killing-my-code-coverage-im-planning-to-exclude-it类似,建议对于 Cobertura,应使用“忽略”属性而不是“排除”。我在设置或文档中没有看到 Jacoco 或 Sonar 的类似内容。

EDIT: Example image from Eclipse attached, after running Jacoco coverage (Sonar shows the same thing in their GUI). This is actual code from one of our classes. Jacoco branch coverage on slf4j logging

编辑2: 我们正在使用 Slf4j 注释。文档在这里:http://docs.groovy-lang.org/next/html/gapi/groovy/util/logging/Slf4j.html http://docs.groovy-lang.org/next/html/gapi/groovy/util/logging/Slf4j.html

此本地转换使用 LogBack 日志记录为您的程序添加了日志记录功能。对名为 log 的未绑定变量的每个方法调用都将映射到对记录器的调用。为此,将在类中插入一个日志字段。如果该字段已存在,则使用此转换将导致编译错误。方法名称将用于确定在记录器上调用什么。

log.name(exp)

被映射到

if (log.isNameLoggable() {
        log.name(exp)
     }

这里的 name 是信息、调试、警告、错误等的占位符。如果表达式 exp 是常量或只是变量访问,则方法调用将不会被转换。但这仍然会导致调用注入的记录器。

希望这能澄清发生了什么。我们的日志语句变成 2 个分支 if,以避免为未启用的日志级别构建昂贵的字符串(据我所知,这是一种常见的做法)。但这意味着为了保证覆盖所有这些分支,我们必须针对每个日志记录级别重复运行每个测试。


我没有找到排除它的通用解决方案,但如果您的代码库允许您这样做,您可以将日志记录语句包装在带有包含“的注释的方法中”生成“在它的名字中。

一个简单的例子:

package org.example.logging

import groovy.transform.Generated
import groovy.util.logging.Slf4j

@Slf4j
class Greeter {

    void greet(name) {
        logDebug("called greet for ${name}")
        println "Hello, ${name}!"
    }

    @Generated
    private logDebug(message) {
        log.debug message
    }
}

很遗憾javax.annotation.Generated不合适,因为它只保留了SOURCE,因此我(被)使用groovy.transform.Generated在这里,但可以轻松地为此目的创建您自己的注释。

我在这里找到了该解决方案:如何添加注释以从 jacoco 代码覆盖率报告中排除方法? https://stackoverflow.com/questions/47824761/how-would-i-add-an-annotation-to-exclude-a-method-from-a-jacoco-code-coverage-re


更新:在 Groovy 中,您可以通过以下特征最优雅地解决它:

package org.example.logging

import groovy.transform.Generated
import groovy.util.logging.Slf4j

@Slf4j
trait LoggingTrait {

    @Generated
    void logDebug(String message) {
        log.debug message
    }
}

...进而...

package org.example.logging

import groovy.util.logging.Slf4j

@Slf4j
class Greeter implements LoggingTrait {

    void greet(name) {
        logDebug "called greet for ${name}"
        println "Hello, ${name}!"
    }

}

不幸的是该物业log被解释为属性Greeter,不属于LoggingTrait,所以你必须附加@Slf4j到特征和实现该特征的类。 尽管如此,这样做还是会为您提供预期的记录器 - 实现类之一:

14:25:09.932 [main] DEBUG org.example.logging.Greeter - called greet for world

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Jacoco 从 Sonar 的条件覆盖范围中排除 groovy slf4j 日志记录 的相关文章

随机推荐

  • 如何在maven antrun插件中执行输入任务

    我创建了一个 Maven 项目 我正在尝试运行外部脚本 在此外部脚本中 我使用 read 命令来提出问题并获得答案 如果我做一个 它会起作用sudo mvn 包 with 执行 maven 插件 http www mojohaus org
  • Android 位图图像缓存

    嗨 我正在 Android 中实现图像缓存 经历过这个 http developer android com training displaying bitmaps cache bitmap html http developer andr
  • 如何在滑块上方添加刻度和标签?

    我尝试使用 Slider 划分看起来不错 值 gt 50 10 20 但是 如何在滑块上方添加刻度和标签 Expect 勾选将根据滑块位置改变颜色 Actual Slider min 0 max 100 value value onChan
  • UITableView的separatorEffect属性有什么用?

    iOS 8 中的新功能是separatorEffect属性 您可以为其分配 UIVisualEffect 有谁知道这是做什么用的吗 我试过了 但我不认为它有任何 呃 视觉效果 我想知道完全相同的事情 所以我放了一个Github https
  • random.seed():它有什么作用?

    我有点困惑什么random seed 在 Python 中是这样的 例如 为什么下面的试验会 一致地 做他们所做的事情 gt gt gt import random gt gt gt random seed 9001 gt gt gt ra
  • wxPython:在现有 wx.Panel 上覆盖 wx.Panel 的好方法

    我有一个 wx Frame 其中有一个主 wx Panel 其中有几个小部件 我想要其中的一个按钮来启动 帮助面板 这个帮助面板可能是一个wx Panel 我希望它覆盖整个主wx Panel 不包括wx Frame的菜单栏 帮助按钮上应该有
  • 如何在 HTML 文件中包含 python 脚本?

    我该如何放置这个Python脚本 a f d s a x 1 scope vars for i in a scope x 1 print a x html 文件里面 像这样 如果你想创建一个html 不一定显示它 html file ope
  • pygame中盒子的连续移动

    我编写了以下代码来创建一个简单的游戏 当您单击键盘上的箭头时 一个框会在游戏中移动一个单位 我试图做到这一点 以便如果我按下任何箭头按钮 盒子将继续朝该方向移动 直到按下另一个箭头 因此 如果我按一次向右箭头而不是快速移动 50 像素 它将
  • 如何使用 ES6 样式导入添加外部 javascript 库?

    我无法准确理解如何在新的 ES6 项目中使用旧的 javascript 库 我正在查看一个使用 webpack 编译 使用 ES6 编写并使用 Babel 转译的 React 项目 每个组件都遵循import from 符号 我想在项目中使
  • 类继承命名

    我想继承 DevExpress ComboBoxEdit 控件 并且想知道将我的类命名为与 DevExpress 类相同的名称是否是不好的做法 这是派生类声明 using System using System Collections Ge
  • 如何在 Jenkins Freestyle 项目中使用可锁定资源插件中的 Groovy 表达式

    这个问题是针对旧版本提出的可锁定资源插件 https wiki jenkins ci org display JENKINS Lockable Resources Plugin 旧版本中的错误自2 1版本以来已得到修复 然而 没有描述如何在
  • 使用 Buildbot 支持多个存储库

    目前 Buildbot 不支持多个存储库 如果需要这一点 则需要运行单独的 Buildbot 实例 我仍然很好奇是否有人想出了一个创造性的解决方法来让这个功能正常工作 Update 这个答案最近收到了一些反对票 请注意 这个答案适用于 20
  • 刚刚通过 NuGet 更新了 ImageResizer,无法运行应用程序,因为它找不到 BundleAttribute

    我只是想更新 Azure 存储 但这意味着我需要更新 ImageResizer AzureReader 并更新应用程序以使用 Net 4 5 2 Azure 站点设置为 Net 4 6 现在我已经拥有了最新版本的所有内容 我已经清理并重建了
  • Prismic - 如何在不暴露访问令牌的情况下进行 API 调用

    我正在构建一个 vue js Web 应用程序 我想对我的 prismic 存储库进行相应的调用 但我不知道如何在不暴露我的访问令牌的情况下执行此操作 我正在使用所示的其余 api 方法here https prismic io docs
  • 背景图像:如果图像很小,如何填充整个div,反之亦然

    我有三个问题 当我尝试在较小尺寸的 div 中使用背景图像时 div 仅显示图像的一部分 如何显示图像的完整或特定部分 我有一个较小的图像 我想在更大的 div 中使用 但不想使用重复功能 CSS 有什么方法可以控制图像的不透明度吗 调整图
  • 如何隐藏 Akka 远程 Actor 来查找?

    我正在运行 Akka 2 0 2 微内核 并希望为不受信任的远程参与者实现身份验证方案 首先想到的是设置一个身份验证参与者 当身份验证成功时 该参与者会返回对工作参与者的引用 但是 我应该如何保护工作参与者不被简单地通过 actorFor
  • R:使用 devtools 自动将 import(data.table) 添加到 NAMESPACE

    如何正确添加import data table to the NAMESPACE自动使用文件devtools 一般来说 如果我的包使用data table我只是手动写入 但是无法使用 export and devtools document
  • 在 p5.js 中放大时精灵模糊

    我试图将 p5 js 中精灵的大小放大一点 系数 2 但渲染时它们看起来很模糊 显然 放大通常不是一个好主意 但是我已经成功地使像素化精灵在原始 JavaScript 中看起来清晰 基于这篇文章 https nluqo github io
  • 谁能用适当的例子向我解释 1NF、2NF、3NF、BCNF 规则?

    这是一个常见的面试问题 我遇到过一次面试 面试官给了我一张桌子 让我告诉他这张桌子是哪种范式 如果它在 NF中 那么将其归一化到下一个NF 我总是对这些正常形式的数据库感到困惑 谁能向我解释这些范式 并举出每个 NF 如何建模到表中的正确示
  • 使用 Jacoco 从 Sonar 的条件覆盖范围中排除 groovy slf4j 日志记录

    我们使用 SonarQube 5 1 和 Jacoco maven 插件 0 7 4 以及我们所有的 slf4j 日志记录语句 例如log debug Something happened 表明仅覆盖了 2 个分支中的 1 个 我明白这是因