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 中来创建一个子模块,但没有真正奏效,这很简单。我在日志中看到 <sonar.jacoco.reportPath>
已弃用,但仍按原样工作,并且似乎在执行时自动替换,或者可以手动更新为 <sonar.jacoco.reportPaths>
或最新版本。在 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 的覆盖率也始终为 0%
SonarQube 单元测试报告不显示 Javascript 文件
在 Postman 中获取 SonarQube 6.3.1 的覆盖率、技术债务、单元测试成功密度和单元测试失败密度 json 数据的 restapis 是啥?