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

标签 java sonarqube code-coverage jacoco sonarqube-scan

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

  • SonarQube 版本:5.6.6
  • Sonar Java 插件版本:4.12.0.11033
  • jacoco 版本:0.8.0

我已经用这些属性填充了 sonar-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 报告给了我一个类的结果:

  • 覆盖率:84%
  • 分支机构覆盖率:71%
  • 错过:9
  • 复杂度:24
  • 错过:6
  • 行:69
  • 错过:0
  • 方法:8
  • 错过:0
  • 类(class):1

SonarQube 显示测量值:

  • 条件覆盖率62.5%
  • 覆盖率81.7%
  • 线路覆盖率92.8%
  • 行覆盖 69
  • 整体条件覆盖率62.5%
  • 总体覆盖率81.7%
  • 整体线路覆盖率92.8%
  • 整体未覆盖分支 15
  • 整体未覆盖线5
  • 未覆盖的分支 15
  • 未覆盖的行5

根据sonar metric definition page ,条件覆盖的 Sonar 键是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)

编辑

这两种工具都使用每行的分支信息来计算覆盖率。 我对我的一些代码进行了测试,“要覆盖的条件”(Sonarqube)的数量与 Jacoco 报告中的“分支”总数相匹配——但我使用了 jacoco 和 Sonarqube/sonar-java 的最新版本。所以除了名称,措施是/应该是相同的。

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

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

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 插件。

关于java - jacoco 分支覆盖和 Sonar 条件覆盖有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49879009/

相关文章:

java - JSoup:请求 JSON 响应

java - Sonarqube 中是否真的需要混淆三元规则?

java - SonarQube 上的 mysql 臃肿

java - JaCoCo 报告在 Jenkins : java. lang.ArrayIndexOutOfBoundsException 中失败

java - 验证是否从 Node.js 安装了 Java

java - Tomcat 7 + log4j-api-2.11.1.jar 中的注解

java - 发生 JNI 错误(java 通过 cmd)

尝试设置自定义 HTML 标签样式时,sonarqube 使用规则 "Unknown type selectors should be removed"给出误报

javascript - CoffeeScript 代码覆盖率

java - 请确认/评论我在 EclEmma Eclipse 插件中看到的分支覆盖率问题