从代码覆盖中排除生成的源而不影响整体代码覆盖

Posted

技术标签:

【中文标题】从代码覆盖中排除生成的源而不影响整体代码覆盖【英文标题】:Exclude generated-sources from code coverage without impacting overall code-coverage 【发布时间】:2016-07-09 20:42:17 【问题描述】:

我有一个项目的代码覆盖率很低。经过深入研究后,我发现 jacoco 代码覆盖率统计数据取决于目标目录而不是 src。

target/generated-sources/delombok/com/

如果我排除目标目录,覆盖率下降 0%。因此,不应该根据代码(src)而不是目标文件夹来衡量代码覆盖率。下面是 SonarQube 的截图。

所以问题是我如何确保代码覆盖率是针对 src 而不是目标测量的?

以下是没有依赖的pom:

 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>removed</groupId>
    <artifactId>xxxx</artifactId>
    <version>0.0.11-SNAPSHOT</version>
    <packaging>war</packaging>



    <build>

        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>cassandra-maven-plugin</artifactId>
                <version>2.1.7-1</version>
                <configuration>
                    <script>$basedir/src/main/cassandra/local_run.cql</script>
                    <cqlVersion>3.2.0</cqlVersion>
                    <startNativeTransport>true</startNativeTransport>
                    <nativeTransportPort>9142</nativeTransportPort>
                    <jmxPort>17199</jmxPort>
                    <storagePort>17000</storagePort>
                    <loadFailureIgnore>false</loadFailureIgnore>
                    <cuLoadFailureIgnore>false</cuLoadFailureIgnore>
                </configuration>
                <executions>
                    <execution>
                        <id>start</id>
                        <goals>
                            <goal>start</goal>
                            <goal>load</goal>
                        </goals>
                        <phase>process-classes</phase> <!--Bind cassandra start and load to process-classes which is the phase that is called up before tomcat is run -->
                    </execution>
                    <execution>
                        <id>stop</id>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                        <!--Bind cassandra stop to generate-test-sources which is the phase that is called up before
                        tests are run. This is because our tests start their own cassandra -->
                        <phase>integration-test</phase>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                        <version>1.7.7</version>
                    </dependency>
                </dependencies>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-release-plugin</artifactId>
            </plugin>

            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok-maven-plugin</artifactId>
            </plugin>
            <!--Needed to add this so that src/main/java is recognized as a source folder -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
            </plugin>

            <!-- Unit Test -->


            <!-- Integration Test -->


            <plugin>
                <artifactId>maven-enforcer-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <warName>activationloginedge</warName>
                </configuration>
            </plugin>

            <!-- Tomcat Integration Test -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <path>/activationloginedge</path>
                </configuration>
                <executions>
                    <execution>
                        <id>tomcat-run</id>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <phase>pre-integration-test</phase>
                        <configuration>
                            <systemProperties>
                                <!-- We want test configuration for running integration tests. -->
                                <archaius.deployment.environment>test</archaius.deployment.environment>
                                <logback-lib.env>filesystem</logback-lib.env>
                            </systemProperties>
                            <fork>true</fork>
                        </configuration>
                    </execution>
                    <execution>
                        <id>tomcat-shutdown</id>
                        <goals>
                            <goal>shutdown</goal>
                        </goals>
                        <phase>post-integration-test</phase>
                    </execution>
                </executions>
            </plugin>
        <plugin>
      <groupId>org.jacoco</groupId>
      <artifactId>jacoco-maven-plugin</artifactId>
      <version>0.7.4.201502262128</version>
      <executions>
        <execution>
          <id>pre-unit-test</id>
          <goals>
            <goal>prepare-agent</goal>
          </goals>
          <configuration>
          <!-- Sets the path to the file which contains the execution data. -->
             <destFile>$project.build.directory/jacoco-ut.exec</destFile>
             <!-- Sets the name of the property containing the settings for JaCoCo runtime agent.-->
             <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 path to the file which contains the execution data. -->
          <dataFile>$project.build.directory/jacoco-ut.exec</dataFile>
          <!-- Sets the output directory for the code coverage report. -->
          <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>
<!-- Sets the path to the file which contains the execution data. -->
    <destFile>$project.build.directory/jacoco-it.exec</destFile>
    <!-- Sets the name of the property containing the settings for JaCoCo runtime agent.-->
    <propertyName>failsafeArgLine</propertyName>
 <

    /configuration>
    </execution>
    <!--   Ensures that the code coverage report for integration tests after  integration tests have been run.-->
    <execution>
        <id>post-integration-test</id>
        <phase>post-integration-test</phase>
        <goals>
                <goal>report</goal>
        </goals>
     <configuration>
    <!-- Sets the path to the file which contains the execution data. -->
    <dataFile>$project.build.directory/coverage-reports/jacoco-it.exec</dataFile>
     <!-- Sets the output directory for the code coverage report. -->
            <outputDirectory>$project.reporting.outputDirectory/jacoco-it</outputDirectory>
        </configuration>
     </execution>
     </executions>
     </plugin>
    <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-surefire-plugin</artifactId>
       <version>2.12.4</version>
       <configuration>
         <!-- Sets the VM argument line used when unit tests are run. -->
         <argLine>$surefireArgLine</argLine>
         <!-- Skips unit tests if the value of skip.unit.tests property is true -->
         <skipTests>$skip.unit.tests</skipTests>
         <!-- Excludes integration tests when unit tests are run. -->
         <excludes>
           <exclude>**/IT*.java</exclude>
         </excludes>
       </configuration>
      </plugin>
    <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.15</version>      <executions>
            <execution>
                <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
                </goals>
          <configuration>
         <!-- Sets the VM argument line used when integration tests are run-->
             <argLine>$failsafeArgLine</argLine>
         <!-- Skips integration tests if the value of skip.integration.tests property is true-->
            <skipTests>$skip.integration.tests</skipTests>      </configuration>
              </execution>
              </executions>
      </plugin>
    </plugins>
        </build>
    </project>

【问题讨论】:

您能否提供有关您的配置的更多详细信息?实际上,代码覆盖率是根据源代码计算的,因此看起来您将“目标”配置为源文件夹之一。 通过删除依赖部分附加了pom 呃,您好像忘记附加(或提供链接)文件@Jeel 抱歉忘记保存添加 pom 的编辑。现在添加到上面了。 【参考方案1】:

好的,Lombok Maven 插件在 Maven 构建期间修改了源文件夹列表,这就是为什么 SonarQube 将 target/generated-sources/delombok 文件夹识别为源文件夹的原因。

为了强制 SonarQube 只考虑您自己的源文件,您应该将以下属性添加到您的 POM:

<properties>
  <sonar.sources>src/main/java</sonar.sources>
</properties>

这将解决您的问题。

【讨论】:

以上是关于从代码覆盖中排除生成的源而不影响整体代码覆盖的主要内容,如果未能解决你的问题,请参考以下文章

nyc (istanbul) 从覆盖率报告中排除测试代码

如何在颤振测试覆盖率中排除文件?

使用 Cobertura 从代码覆盖中排除方法

如何从业力代码覆盖率报告中排除文件?

从 .net 6 的代码覆盖范围中排除 Program.cs [重复]

从 Xcode 7 的覆盖率统计中排除代码