jacoco 分支覆盖和 Sonar 条件覆盖有什么区别?

What is the difference between jacoco branch coverage and Sonar condition coverage?

我正在尝试使用 SonarQube 扫描仪(版本 3.1.0.1141)分析 java 代码。

我已经用这些属性填充了声纳-project.properties :

# Sonar sources and metadata
sonar.language=java
sonar.sources=src/main
sonar.java.source=1.8
sonar.sourceEncoding=UTF-8
sonar.java.binaries=target/classes
sonar.java.libraries=target/lib

sonar.tests=src/test
sonar.java.coveragePlugin=jacoco
sonar.junit.reportsPath=target/surefire-reports
sonar.surefire.reportsPath=target/surefire-reports

虽然 jacoco 报告给了我这个结果 class :

SonarQube 显示测量值:

根据sonar metric definition page,条件覆盖的声纳键是branch_coverage,所以我认为条件和分支覆盖是一回事。

如何解释不同的结果?

假设你有一些构造

if(a == 1 && b == 2) {
  //do this
} else {
  //do that
}

你有两个分支

  • 这样做
  • 这样做

还有两个条件

  • a == 1 (cond1)
  • b == 2 (cond2)

如果你有两个测试用例

  • 测试(a == 1, b == 2)
  • 测试(a == 2,b == 2)

你覆盖了两个分支,因为 (cond1 && cond2) 的组合条件不是假就是真,

但是你只完全覆盖了 cond1 而只覆盖了 cond2 的一半,即 75% 的条件覆盖率。

要获得完整的条件覆盖,您需要进行额外的测试

  • 测试(a == 1, b == 1)

编辑

这两种工具都使用每行的分支信息来计算覆盖率。 我 运行 对我的一些代码进行了测试,并且 "conditions to cover" (Sonarqube)的数量与 Jacoco 报告中的总数 "Branches" 相匹配 - 但我使用了最新版本的 jacoco 和Sonarqube/sonar-java。所以除了名字,但是措施are/should是一样的。

但是鉴于您提供的数字,总的来说您的分析似乎有些奇怪。不仅百分比值不同,绝对值也不同(Jacoco 中有 9 个未发现的分支,而 Sonarqube 中有 15 个未发现的分支)。

所以我检查了您使用的版本 - jacoco 0.8.0 和 sonar-java 插件 v4.11.0.11033,它使用 jacoco 0.7.9。

release notes for Jacoco 0.8.0

During creation of reports various compiler generated artifacts are filtered out, which otherwise require unnecessary and sometimes impossible tricks to not have partial or missed coverage:

  • Methods valueOf and values of enum types (GitHub #491).
  • Private empty no-argument constructors (GitHub #529).
  • Methods annotated with @lombok.Generated to better integrate with Lombok >= 1.16.14. Initial analysis and contribution by Rüdiger zu Dohna (@t1) (GitHub #513).
  • Methods annotated with @groovy.transform.Generated to better integrate with Groovy >= 2.5.0. Thanks to Andres Almiray (@aalmiray) for adding the annotation to Groovy (GitHub #610).
  • Part of bytecode for synchronized blocks (GitHub #501).
  • Part of bytecode for try-with-resources statements (GitHub #500).
  • Part of bytecode for finally blocks (GitHub #604).
  • Part of bytecode for switch statements on java.lang.String values (GitHub > #596).

所以我最好的猜测是,Jacoco 0.8.0 生成的报告过滤掉了一些提到的生成的工件,有效地减少了分支总数。然而,Sonar-Java 使用 Jacoco 0.7.9,它不会过滤掉生成的伪影,因此数量更高(覆盖率更低)。

也许你应该将你的 jacoco 版本降级到 0.7.9 或者升级 sonar-java 插件。