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

时间:2018-04-17 13:08:14

标签: 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
  • 课程: 1

SonarQube显示措施:

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

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

如何解释不同的结果?

1 个答案:

答案 0 :(得分:0)

鉴于你有一些构造为

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

你有两个分支

  • 这样做
  • 那样做

两个条件

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

如果您有两个测试用例

  • test(a == 1,b == 2)
  • test(a == 2,b == 2)

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

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

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

  • test(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阅读

  

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

     
      
  • 方法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插件。