我有一个使用 SonarQube 来分析我的代码的项目。正如标题所暗示的那样,尽管我进行了多次 Junit 测试,但 SQ 报告(在我的服务器上)中的覆盖率指标始终显示为 0。我目前运行以下命令
clean package deploy sonar:sonar -Dsonar.projectKey=SomeName -Dmaven.test.skip=true
在 Jenkins 中构建我的项目时(Jenkins Maven 项目)。
我在不同的项目中遇到了类似的问题。我设法通过 this 文章解决了这个问题。然而,这一次并没有帮助。经过一番搜索,我找到了 article 1 和 article 2(还有一些类似的想法)。两人都提出了一些很好的建议,但不幸的是没有任何效果。
我注意到我每次都会收到以下警告(不知道是什么原因)
Cobertura report not found at /var/lib/jenkins/jobs/SomeProjectName/workspace/SomeFolderName/target/site/cobertura/coverage.xml
起初,我尝试添加 cobertura 插件(如建议的 here),但这只是删除了警告(报告中的覆盖率仍然为 0)。我目前的理解是它覆盖了 Jacoco,但我没有找到原因或解决方案。
我的插件:
<build>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>scala-test-compile</id>
<phase>process-test-resources</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<verbose>true</verbose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<finalName>uber-${project.artifactId}-${project.version}</finalName>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
</configuration>
</execution>
<execution>
<id>pre-integration-test</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-integration-test</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.9.2</version>
<executions>
<execution>
<configuration>
<outputDirectory>${project.basedir}/target/generated-sources</outputDirectory>
<sourceDirectory>${project.basedir}/src/main/resources/</sourceDirectory>
</configuration>
<goals>
<goal>schema</goal>
<goal>protocol</goal>
<goal>idl-protocol</goal>
</goals>
<id>schemas</id>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
我的属性:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
</properties>
答案 0 :(得分:1)
有一些事情必须正确设置才能使您的测试覆盖率显示在 SonarQube 中。其中一些设置具有可能有效的默认值,但我尽量避免使用魔法默认值,以确保我的设置彼此一致。
Surefire 和 Jacoco 必须具有彼此一致的设置,并且 SonarQube 必须知道在哪里可以找到覆盖数据文件。
我将推荐一些属性值供您使用。
sonar.coverage.jacoco.xmlReportPaths: ${basedir}/target/jacoco_report/jacoco.xml
jacoco.path: ${basedir}/target/jacoco_report
然后,这是您的 jacoco 插件的摘录:
<!-- Prepares the property pointing to the JaCoCo runtime agent which
is passed as VM argument when Maven the Surefire plugin is executed. -->
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<!-- Ensures that the code coverage report for unit tests is created
after unit tests have been run. -->
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the output directory for the code coverage report. -->
<outputDirectory>${jacoco.path}</outputDirectory>
</configuration>
</execution>
最后,这是在 Surefire 插件的配置块中:
<!-- Sets the VM argument line used when unit tests are run. -->
<argLine>${surefireArgLine}</argLine>
但是,在您的情况下,您遇到了一个非常高级的问题,即使您正确完成了所有这些设置,也会导致覆盖率为零。感谢@Ian W 指出这一点。
当我看到你写“尽管我有多个 Junit 测试”时,我相信你实际上是在执行单元测试。您的命令行上有“-Dmaven.test.skip=true”,这会导致它不执行任何单元测试。删除那个。