【发布时间】:2016-04-08 11:23:56
【问题描述】:
我们正在使用带有 Jacoco maven 插件 0.7.4 的 SonarQube 5.1,并且我们所有的 slf4j 日志记录语句(例如 log.debug('Something happened'))显示只有 2 个分支中的 1 个被覆盖。我知道这是因为 slf4j 内部做了一个if debug,这很好,但我们不希望这会影响我们的数字。我们对测试 slf4j 不感兴趣,我们宁愿不为不同的日志记录级别多次运行每个测试。
那么,我们如何告诉 Sonar 和/或 Jacoco 将这些行排除在覆盖范围之外?它们都具有可配置的文件排除项,但据我所知,这些仅用于将您自己的类排除在覆盖范围之外(使用目标目录),而不是导入的库。无论如何,我尝试将groovy.util.logging.*' 添加到排除列表中,但它没有做任何事情。
logger.isDebugEnabled() is killing my code coverage. I'm planning to exclude it while running cobertura 类似并建议对于 Cobertura 应使用“忽略”属性而不是“排除”。我在设置或文档中看不到 Jacoco 或 Sonar 的类似内容。
编辑: 在运行 Jacoco 覆盖后附上来自 Eclipse 的示例图像(Sonar 在其 GUI 中显示相同的内容)。这是来自我们的一个类的实际代码。
编辑 2: 我们正在使用 Slf4j 注释。这里的文档: 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 是 info、debug、warning、error 等的占位符。如果表达式 exp 是常量或仅是变量访问,则不会转换方法调用。但这仍然会导致对注入的记录器的调用。
希望这能澄清发生了什么。我们的日志语句变成了 2 个分支 if,以避免为未启用的日志级别构建昂贵的字符串(据我所知,这是一种常见的做法)。但这意味着,为了保证覆盖所有这些分支,我们必须针对每个日志记录级别重复运行每个测试。
【问题讨论】:
-
您能否发布一个小代码示例,该示例仅显示两个条件之一?准确地说:这是 JaCoCo 方面的问题,SonarQube 仅显示您的覆盖工具的结果。
-
@benzonico 谢谢,添加了截图。
-
这在很多方面听起来很奇怪:您介意精确
log对象的类型并最终反编译您的类的.class 文件并共享生成的相关字节码指令吗? -
@benzonico 请参阅 EDIT2。希望这可以澄清事情。
-
嗯,事实上,你自己回答得差不多了。您遇到的主要问题是日志行在编译时会在字节码中生成一个分支。当 JaCoCo 检测字节码时,您最终只覆盖了这些字节码指令分支的一侧。在 sonarqube 方面没有太多工作要做,最终问题可能会报告给 JaCoCo,因为它与 java 中的 try-with-resources 问题相同。
标签: unit-testing groovy sonarqube code-coverage jacoco-maven-plugin