【问题标题】:SonarQube coverage is always 0SonarQube 覆盖率始终为 0
【发布时间】:2021-05-09 23:51:42
【问题描述】:

我有一个项目使用 SonarQube 来分析我的代码。正如标题所示,尽管我进行了多次 Junit 测试,但 SQ 报告(在我的服务器上)中的覆盖率指标始终为 0。我目前运行以下命令

clean package deploy sonar:sonar -Dsonar.projectKey=SomeName -Dmaven.test.skip=true

在 Jenkins 中构建我的项目时(Jenkins Maven 项目)。

前段时间我在不同的项目中遇到了类似的问题。我设法通过this 文章解决了这个问题。然而,这一次并没有帮助。经过一番搜索,我找到了article 1article 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>

【问题讨论】:

  • 相当肯定@david-m-karr 有合理的建议,但最基本的是,您必须执行单元测试(正确配置 jacoco 仪器)以确定覆盖范围。SonarQube juat repots on what jacoco测量。只要你有-Dmaven.test.skip=true,你就会得到一个零。
  • @IanW 嘿!好点,现在我删除了测试跳过,这更有意义。谢谢!

标签: maven jenkins sonarqube


【解决方案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”,这会导致它不执行任何单元测试。删除它。

【讨论】:

  • 感谢您的回复!不幸的是,我无法将&lt;argLine&gt;${surefireArgLine}&lt;/argLine&gt; 添加到我的surefire 插件中:它表示该符号无法识别(jacoco 插件和surefire 插件中的名称相同,所以不是错字)。
  • 您必须使用实际详细信息更新您的帖子,以便我们告诉您在这里做错了什么。
  • 基本上,您必须执行单元测试(正确配置 jacoco 仪器)以确定覆盖范围。SonarQube 仅报告 jacoco 测量的内容。只要你有-Dmaven.test.skip=true,你就会得到一个零。 @david-m-karr,请将其添加到您的回复中。
猜你喜欢
  • 2021-10-19
  • 2022-07-01
  • 2016-11-15
  • 2021-02-11
  • 2021-06-30
  • 2013-09-16
  • 2021-08-01
  • 2011-04-27
  • 1970-01-01
相关资源
最近更新 更多