gpt4 book ai didi

unit-testing - 使用 Jacoco 从 Sonar 中的条件覆盖中排除 groovy slf4j 日志记录

转载 作者:行者123 更新时间:2023-12-04 11:04:19 24 4
gpt4 key购买 nike

我们使用 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() is killing my code coverage. I'm planning to exclude it while running cobertura类似,并建议对于 Cobertura 应使用“忽略”属性而不是“排除”。我在设置或文档中没有看到 Jacoco 或 Sonar 的类似内容。

编辑:
在运行 Jacoco coverage 后附上来自 Eclipse 的示例图像(Sonar 在其 GUI 中显示相同的内容)。这是来自我们的一个类的实际代码。
Jacoco branch coverage on slf4j logging

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

This local transform adds a logging ability to your program using LogBack logging. Every method call on a unbound variable named log will be mapped to a call to the logger. For this a log field will be inserted in the class. If the field already exists the usage of this transform will cause a compilation error. The method name will be used to determine what to call on the logger.

log.name(exp)

is mapped to


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

Here name is a place holder for info, debug, warning, error, etc. If the expression exp is a constant or only a variable access the method call will not be transformed. But this will still cause a call on the injected logger.



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

最佳答案

我没有找到排除它的通用解决方案,但是如果您的代码库允许您这样做,您可以将您的日志记录语句包装在一个方法中,该方法的名称中包含“ Generated ”。
一个简单的例子:

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的保留, 因此我 (ab) 使用了 groovy.transform.Generated在这里,但可以轻松地为此目的创建自己的注释。
我在这里找到了解决方案: How would I add an annotation to exclude a method from a jacoco code coverage report?

更新:在 Groovy 中,你可以用一个 trait 最优雅地解决它:
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}!"
}

}
不幸的是属性(property) log被解释为 Greeter 的属性,不是 LoggingTrait ,所以你必须附上 @Slf4j到特性和实现特性的类。
尽管如此,这样做会为您提供预期的记录器 - 实现类之一: 14:25:09.932 [main] DEBUG org.example.logging.Greeter - called greet for world

关于unit-testing - 使用 Jacoco 从 Sonar 中的条件覆盖中排除 groovy slf4j 日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34598084/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com