代码之家  ›  专栏  ›  技术社区  ›  Alban

jacoco分支覆盖和声纳条件覆盖之间有什么区别?

  •  8
  • Alban  · 技术社区  · 7 年前

    我试图用SonarQube扫描器(版本3.1.0.1141)分析java代码。

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

    我已经完成了声纳项目。具有这些属性的属性:

    # 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 report为我提供了一个类的结果:

    • 覆盖范围: 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\u覆盖,所以我认为条件和branch覆盖是一样的。

    如何解释不同的结果?

    1 回复  |  直到 7 年前
        1
  •  10
  •   Gerald Mücke    7 年前

    假设你有一些构造

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

    你有两个分支

    • 执行此操作
    • 这样做吧

    和两个条件

    • a==1(条件1)
    • b==2(条件2)

    如果您有两个测试用例

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

    您正在覆盖这两个分支,因为(cond1和cond2)的组合条件为false或true,

    但你只覆盖cond1的全部,只覆盖cond2的一半,即75%的条件覆盖率。

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

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

    编辑

    这两种工具都使用每行的分支信息计算覆盖率。 我在我的一些代码上运行了一个测试,“要覆盖的条件”(Sonarqube)的数量与Jacoco报告中的总“分支”数量相匹配,但我使用了Jacoco和Sonarqube/sonar java的最新版本。因此,除了名称,但度量值是/应该是相同的。

    但考虑到你提供的数字,你的分析总体上似乎有些奇怪。不仅百分比值不同,绝对值也不同(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 阅读

    在创建报告的过程中,各种编译器生成的工件被过滤掉,否则需要不必要的、有时甚至不可能的技巧来避免部分覆盖或遗漏覆盖:

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

    因此,我在这里的最佳猜测是,Jacoco 0.8.0生成的报告过滤掉了一些提到的生成工件,从而有效地减少了分支的总数。然而,Sonar Java使用的是Jacoco 0.7.9,它没有过滤掉生成的工件,因此数字更高(覆盖率更低)。

    也许您应该将jacoco版本降级到0.7.9或升级sonar java插件。