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

我正在尝试使用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
  • 课程: 1

SonarQube显示措施:

  • 条件覆盖率62,5%
  • 覆盖率81,7%
  • 线路覆盖率92,8%
  • 线路覆盖69
  • 总体条件覆盖率62,5%
  • 总体覆盖率81,7%
  • 总体线路覆盖率92,8%
  • 整体未覆盖的分支15
  • 整体未覆盖的线条5
  • 未覆盖的分支15
  • 裸露的线条5

根据声纳度量定义页面 ,条件覆盖的声纳键是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。

Jacoco 0.8.0的发行说明阅读

在创建报告期间,会过滤掉各种编译器生成的工件,否则需要不必要的,有时甚至是不可能的技巧,以避免部分或错过覆盖:

  • 方法valueOf和枚举类型的值(GitHub#491)。
  • 私有空无参数构造函数(GitHub#529)。
  • 使用@ lombok.Generated注释的方法可以更好地与Lombok> = 1.16.14集成。 RüdigerzuDohna(@ t1)(GitHub#513)的初步分析和贡献。
  • 使用@ groovy.transform.Generated注释的方法可以更好地与Groovy> = 2.5.0集成。 感谢Andres Almiray(@aalmiray)将注释添加到Groovy(GitHub#610)。
  • 同步块的字节码的一部分(GitHub#501)。
  • try-with-resources语句的字节码的一部分(GitHub#500)。
  • finally块的字节码的一部分(GitHub#604)。
  • java.lang.String值上的switch语句的字节码的一部分(GitHub>#596)。

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

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