SonarQube 没有获得单元测试覆盖率

Posted

技术标签:

【中文标题】SonarQube 没有获得单元测试覆盖率【英文标题】:SonarQube not picking up Unit Test Coverage 【发布时间】:2014-04-06 03:19:23 【问题描述】:

我在获取 jacoco 分析报告时遇到了声纳问题。然而,Jenkins 能够获取报告并显示结果。 我的项目是由 Jenkins 构建的 Maven 构建。 jacoco 报告由 maven 生成(在 pom 中配置)。 Sonar 使用 Jenkins 插件执行。

这是我在 SonarQube 上看到的:

这是我在詹金斯看到的项目报告。

maven 插件配置:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.6.4.201312101107</version>
    <executions>
      <execution>
        <id>default-prepare-agent</id>
        <goals>
            <goal>prepare-agent</goal>
        </goals>
      </execution>
      <execution>
        <id>default-report</id>
        <phase>prepare-package</phase>
        <goals>
            <goal>report</goal>
        </goals>
      </execution>
      <execution>
          <id>default-check</id>
          <goals>
              <goal>check</goal>
          </goals>
      </execution>
    </executions>
</plugin>

Jenkins 声纳插件配置

【问题讨论】:

控制台输出中的某处应显示“代码覆盖率设置为 0%...”,该信息对调试您的问题很有用。有两件事不看就想到了:1.您应该设置 sonar.binaries 属性并将其指向您编译的类文件 2.您应该设置 sonar.tests 并将其指向未编译的测试文件。 3.你应该在调试模式下编译(你可能已经我看不出来了) @Cole9350 所以我在输出中看到的错误是:项目覆盖率设置为 0%,因为没有包含类的目录。 我尝试将 sonar.binaries 设置为类目录的根目录 - /target/classes - 但这导致错误提示找不到它们 更正 我再次尝试设置类的完全限定路径,现在我可以看到代码覆盖率。但是我知道当 jacoco 传感器运行时会看到错误:没有关于每次测试覆盖率的信息。 好!你快到了。第一个错误表明您没有设置 sonar.binaries。现在你的错误是告诉你设置 sonar.tests 就像我在 (2) 中提到的那样......之后我很确定声纳会覆盖范围 @Cole9350 :将声纳从 4.0 升级到 4.5.1 后,我也面临同样的问题。之前它用于生成代码覆盖率,但升级后没有关于代码覆盖率的信息,当我通过控制台输出时,我看到目标文件夹下生成了 jacoco.exec 文件,但列出了 Cobertura 传感器而不是 jacocoSensor 用于分析代码覆盖率。 【参考方案1】:

您缺少一些重要的声纳属性,这是我的一个构建示例:

sonar.jdbc.dialect=mssql
sonar.projectKey=projectname
sonar.projectName=Project Name
sonar.projectVersion=1.0
sonar.sources=src
sonar.language=java
sonar.binaries=build/classes
sonar.tests=junit
sonar.dynamicAnalysis=reuseReports
sonar.junit.reportsPath=build/test-reports
sonar.java.coveragePlugin=jacoco
sonar.jacoco.reportPath=build/test-reports/jacoco.exec

Jenkins 控制台输出中的错误对于让代码覆盖率正常工作非常有用。

项目覆盖率设置为 0%,因为没有包含类的目录。 表示您没有正确设置 Sonar.Binaries 属性

没有关于每次测试覆盖率的信息 表示您没有正确设置 Sonar.Tests 属性

未收集覆盖信息。也许您忘记在编译的类中包含调试信息? 表明 sonar.binaries 属性设置正确,但这些文件不是在调试模式下编译的,它们需要

【讨论】:

这些设置并非都是必需的(例如,不推荐使用动态分析)。我为二进制属性投票赞成,我设置错了。 嗨,我对 android-Kotlin 有相同的配置,构建生成成功,除了代码覆盖率之外,一切都准备就绪。任何可能会错过的建议。仅供参考:我使用的配置与您提到的完全相同。 @CoDe 你是怎么解决的?我有类似的问题,但使用 Kotlin 文件 - ***.com/q/70151110/8762338 已经很久了,很难回忆。对不起 !但如果你有具体的问题我可以试试。【参考方案2】:

基于https://github.com/SonarSource/sonar-examples/blob/master/projects/tycho/pom.xml,以下 POM 适合我:

<properties>
    <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
    <sonar.jacoco.reportPath>$project.basedir/../target/jacoco.exec</sonar.jacoco.reportPath>
</properties>
<build>
    <plugins>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.7.0.201403182114</version>
            <executions>
                <execution>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <destFile>$sonar.jacoco.reportPath</destFile>
            </configuration>
        </plugin>
    </plugins>
</build>
将目标文件设置为报告路径可确保 Sonar 准确读取 JaCoCo 生成的文件。 报告路径应位于项目目录之外,以考虑跨项目覆盖(例如,在 Tycho 的情况下,约定将单独的项目用于测试)。 reuseReports 设置可防止在读取 JaCoCo 报告文件之前将其删除! (自 4.3 起,this is the default 已弃用。)

那我就跑

mvn clean install
mvn sonar:sonar

【讨论】:

这个建议对我在 OpenShift 集群上的 Sonarqube 有帮助【参考方案3】:

Jenkins 不显示覆盖结果,因为这是 jenkins jacoco 插件和 maven jacoco 插件之间的版本兼容性问题。 在我这边,我使用更新版本的 maven jacoco 插件修复了它

<build>
   <pluginManagement>
     <plugins>
       <plugin>
         <groupId>org.jacoco</groupId>
         <artifactId>jacoco-maven-plugin</artifactId>
         <version>0.7.9</version>
       </plugin>
     <plugins>
   <pluginManagement>
<build>

【讨论】:

【参考方案4】:

在 pom.xml 中包含 sunfire 和 jacoco 插件和 运行 maven 命令,如下所示。

mvn jacoco:prepare-agent jacoco:report sonar:sonar

<properties>
    <surefire.version>2.17</surefire.version>
    <jacoco.version>0.7.2.201409121644</jacoco.version>

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>$surefire.version</version>
        </plugin> 

        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>$jacoco.version</version>

            <executions>
                <execution>
                    <id>default-prepare-agent</id>
                    <goals><goal>prepare-agent</goal></goals>
                </execution>
                <execution>
                    <id>default-report</id>
                    <phase>prepare-package</phase>
                    <goals><goal>report</goal></goals>
                </execution>
            </executions>
        </plugin>
    </plugins>

【讨论】:

【参考方案5】:

我遇到了类似的问题,0.0% 的覆盖率和没有单元测试计数在 SonarQube 6.7.2 的 Sonar 仪表板上: Maven:3.5.2, 爪哇:1.8, Jacoco:使用 7.0/7.9/8.0, 操作系统:Windows

在为 maven 多模块项目寻找正确解决方案进行了很多努力之后,不像这里的单模块项目,我们需要说从单个模块中选择 jacoco 报告并合并到一个报告中,所以解决了这个配置的问题作为我的父 pom 看起来像:

 <properties>
            <!--Sonar -->
            <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
            <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
        <sonar.jacoco.reportPath>$project.basedir/../target/jacoco.exec</sonar.jacoco.reportPath>
            <sonar.language>java</sonar.language>

        </properties>

        <build>
            <pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <configuration>
                            <source>1.5</source>
                            <target>1.5</target>
                        </configuration>
                    </plugin>

                    <plugin>
                        <groupId>org.sonarsource.scanner.maven</groupId>
                        <artifactId>sonar-maven-plugin</artifactId>
                        <version>3.4.0.905</version>
                    </plugin>

                    <plugin>
                        <groupId>org.jacoco</groupId>
                        <artifactId>jacoco-maven-plugin</artifactId>
                        <version>0.7.9</version>
                        <configuration>
                            <destFile>$sonar.jacoco.reportPath</destFile>
                            <append>true</append>
                        </configuration>
                        <executions>
                            <execution>
                                <id>agent</id>
                                <goals>
                                    <goal>prepare-agent</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>

                </plugins>
            </pluginManagement>
        </build>

我尝试了一些其他选项,例如 jacoco-aggregate 甚至通过将其包含在父 pom 中来创建一个子模块,但没有真正奏效,这很简单。我在日志中看到 &lt;sonar.jacoco.reportPath&gt; 已弃用,但仍按原样工作,并且似乎在执行时自动替换,或者可以手动更新为 &lt;sonar.jacoco.reportPaths&gt; 或最新版本。在 cmd 中进行设置后,从 mvn clean install 然后 mvn org.jacoco:jacoco-maven-plugin:prepare-agent install (检查项目的目标文件夹是否 jacoco. exec 已创建)然后执行 mvn sonar:sonar ,这是我尝试过的方法,如果有其他最佳解决方案可用,请告诉我。希望这会有所帮助!如果没有,请发布您的问题..

【讨论】:

【参考方案6】:

我遇到了同样的问题,我的挑战是正确配置 Jacoco 并为 Sonar 配置正确的参数。我将简要解释一下,我最终是如何让 SonarQube 正确显示测试结果和测试覆盖率的。

在你的项目中,你需要在你的 pom 或父 pom 中安装 Jacoco 插件(你已经得到了这个)。此外,您需要用于显示测试结果的 maven-surefire-plugin。运行 maven 构建时会自动生成所有测试报告。棘手的部分是为声纳找到正确的参数。并非所有参数似乎都适用于正则表达式,您必须为这些参数使用逗号分隔的列表(我认为文档并不是很好)。以下是我使用的参数列表(我在 Bamboo 中使用它们,如果使用 sonar.properties 文件,可以省略“-D”):

-Dsonar.branch.target=master (in newer version of SQ I had to remove this, so that master branch is analyzed correctly; I used auto branch checkbox in bamboo instead)
-Dsonar.working.directory=./target/sonar
-Dsonar.java.binaries=**/target/classes
-Dsonar.sources=./service-a/src,./service-b/src,./service-c/src,[..]
-Dsonar.exclusions=**/data/dto/**
-Dsonar.tests=.
-Dsonar.test.inclusions=**/*Test.java [-> all your tests have to end with "Test"]
-Dsonar.junit.reportPaths=./service-a/target/surefire-reports,./service-b/target/surefire-reports,
./service-c/target/surefire-reports,[..]
-Dsonar.jacoco.reportPaths=./service-a/target/jacoco.exec,./service-b/target/jacoco.exec,
./service-c/target/jacoco.exec,[..]
-Dsonar.projectVersion=$bamboo.buildNumber
-Dsonar.coverage.exclusions=**/src/test/**,**/common/**
-Dsonar.cpd.exclusions=**/*Dto.java,**/*Entity.java,**/common/**

如果您在项目中使用 Lombok,那么您还需要一个 lombok.config 文件来获得正确的代码覆盖率。 lombok.config 文件位于项目的根目录,内容如下:

config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true

【讨论】:

嗨,你能帮我解决这个类似的问题吗***.com/q/70151110/8762338【参考方案7】:

surefire 和 jacoco 插件中存在 argLine 配置会停止 jacoco 报告的生成。 argLine 应该在属性中定义

<properties>
  <argLine>your jvm options here</argLine>
</properties>

【讨论】:

【参考方案8】:

对我来说,sonarqube 仪表板中没有显示百分比覆盖率。我在我们的 pom.xml 中添加了下面的属性来工作。

<sonar.binaries>$project.basedir/../target/classes</sonar.binaries>

【讨论】:

以上是关于SonarQube 没有获得单元测试覆盖率的主要内容,如果未能解决你的问题,请参考以下文章

单元测试覆盖在 Sonarqube 中不可见

即使我添加了测试单元,sonarqube 的覆盖率也始终为 0%

SonarQube 单元测试报告不显示 Javascript 文件

iOS单元测试-04-覆盖率上传sonarqube

在 Postman 中获取 SonarQube 6.3.1 的覆盖率、技术债务、单元测试成功密度和单元测试失败密度 json 数据的 restapis 是啥?

上传NUnit的单元测试结果和OpenCover的单元测试覆盖率到SonarQube服务中