SonarQube 的覆盖范围缺少 Jacoco 报告所涵盖的一些行

SonarQube coverage missing some lines covered by Jacoco report

当我 运行 使用 Jacoco 代理进行单元测试时,我的本地 Jacoco 报告与 SonarQube 上的覆盖范围之间存在一些差异。这似乎只影响包含嵌套 classes 的文件。本地生成的报告有外class和所有内classes的覆盖信息,但是SonarQube上的覆盖数据只包括内classes.

例如,Foo.java 包含外部 class、Foo 和内部 classes、Bar 和 Baz。

我的本地报告显示 class Foo 的指令覆盖率为 26%,class Foo.Bar 的指令覆盖率为 46%,class Foo.Baz 的指令覆盖率为 0% ; Foo.java 的总体指令覆盖率为 30%。 SonarQube 覆盖率页面为 Foo.java 提供了 15% 的线路覆盖率。我知道线路覆盖率不等于指令覆盖率,但我希望数字更接近。经过进一步检查,我注意到在 SonarQube 上 Foo.java 的基于文件的覆盖视图中,外部 class Foo 中的所有行都标记为 "Not covered by unit tests" 并且唯一标记为覆盖的行是我期望的 Foo.Bar 中的那些。这种差异弥补了 Jacoco 报告和 SonarQube 之间大约 15% 的差距。我在本地扫描器日志或服务器分析日志中没有看到任何异常。

我是 运行 JaCoCo 0.7.7.201606060606,Java 版本 1.8.0_73,本地是 sonar-scanner 2.8。服务器是 运行ning Java 版本 1.8.0_66-b17,SonarQube 版本 5.6.3,SonarQube Java 插件版本 4.2.1.6971.

如果有任何建议,我将不胜感激,如果有帮助,我很乐意提供更多详细信息。

将 "instructions" 与其他任何东西进行比较就像将苹果和橙子进行比较 - 它们并不代表同一事物。单行代码通常包含许多字节码指令。因此,期望 "instruction coverage" 接近 "line coverage" 是错误的,例如:如果您总共有 10 行 100 条指令,并且用 20 条指令覆盖了 1 行,则错过了 80% 的指令,但是错过了 90% 的台词。

查看 http://www.eclemma.org/jacoco/trunk/doc/counters.html about counters that JaCoCo provides. And http://docs.sonarqube.org/display/SONAR/Metric+Definitions SonarQube 显示的内容。指令覆盖仅在 JaCoCo 中呈现。

如果您看到 SonarQube 显示的 Foo.java 和 JaCoCo 显示的覆盖线之间的差异,则您的问题不清楚。如果有,请提供截图。

事实证明,用于 运行 单元测试(也用于生成我的本地报告)的 class 文件与 sonar-scanner 使用的文件不同。这是因为在编译、单元测试和本地报告生成之后,bnd 在 class 文件上 运行 并重写 class 文件 @Component classes.因为 sonar-scanner 在 bnd 之后是 运行,所以它会看到不同的 class 文件。看来我的问题不是内部与外部 classes,而是 OSGi 组件与非组件; class Foo 是一个 OSGi 组件,而内部 classes 不是。

当我 运行 扫描器扫描 Jacoco 代理使用的相同 classes 文件时,SonarQube 报告的 Foo.java 行覆盖率为 27%(而不是 15% ),并且基于文件的覆盖视图与我的本地报告匹配。