maven构建中的代码覆盖 - 由于缺少类目录而跳过JaCoCo执行

时间:2016-05-24 10:02:28

标签: java maven code-coverage jacoco

如果我有一个项目但是现在我有一个多模块项目,我能够使代码覆盖正常工作。

我的应用程序是在api项目中构建的,我的所有集成测试都在一个单独的项目中运行,该项目使用前面模块构建的artefact。

构建运行但我没有得到代码覆盖率报告,而是收到信息消息:

Skipping JaCoCo execution due to missing classes directory

我的覆盖率报告文件jacoco-it.exec已创建,但似乎jacoco插件需要运行测试的项目中的类。

有人可以告诉我,当班级在另一个模块中时,我需要做些什么才能创建一份报道?

4 个答案:

答案 0 :(得分:5)

我已经设法通过反复试验获得各种解决方法。

似乎jacoco插件很乐意创建没有类的exec文件,但没有它们就不会创建报告,我不明白jacoco是如何在内部工作所以如果有人知道你能解释一下吗?

我也不确定我所做的事情是否可靠但似乎确实报告了我的硒驱动测试的覆盖范围。

我自己提出的(可能)解决方案是使用maven资源插件将目标\ cargo ..目录中war文件中爆炸的类复制到target \ classes目录中: / p>

 <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.7</version>
        <executions>
          <execution>
            <id>copy-resources</id>             
            <phase>pre-integration-test</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${basedir}/target/classes</outputDirectory>
              <resources>          
                <resource>
                  <directory>${basedir}/target/cargo/configurations/tomcat7x/webapps/calculator-api/WEB-INF/classes</directory>
                  <filtering>false</filtering>
                  <excludes>
                        <exclude>**/*Config*.*</exclude>
                        <exclude>**/*Initialiser*.*</exclude>
                  </excludes>
                </resource>
              </resources>              
            </configuration>            
          </execution>
        </executions>
    </plugin>

这似乎让jacoco插件保持高兴,我得到了我的代码覆盖率,虽然看起来插件现在忽略了我的排除列表。

有人知道这实际上是否是一个解决方案,它似乎&#39;工作,但我无法在网上找到这是一个推荐的方法,我也不确定为什么jacoco代理设置的排除选项似乎不再起作用。

我设法绕过jacoco插件而不是排除文件,只是不用资源插件复制它们但我仍然不明白jacoco是如何工作的。

答案 1 :(得分:1)

尽管jacoco:report-aggregate是用于有关依赖项的汇总报告的,但在我的情况下却不起作用-我使用的项目结构如下:

project
└─ module-api   ⇦ API definition
└─ module-spec  ⇦ module with black box tests through the API
└─ module-impl1 ⇦ implementation 1 of the API
└─ module-impl2 ⇦ another implementation of the API
└─ module-test1 ⇦ some dependencies + impl1, apply the tests from spec
└─ module-test2 ⇦ some dependencies + impl2, apply the tests from spec

在这种情况下,report-aggregate生成了一个空报告。 module-test1和module-test2项目具有POM打包类型,也不适合在它们上运行report,因为它需要target / classes目录中的类。

我的解决方案

我将jacoco插件配置为在项目的target / classes目录中转储它要检测的类<classDumpDir>${project.build.outputDirectory}</classDumpDir>

这使常规report目标得以实现。完整的代码是:

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.5</version>
  <configuration>
    <destFile>${project.build.directory}/coverage-reports/code-coverage.exec</destFile>
    <dataFile>${project.build.directory}/coverage-reports/code-coverage.exec</dataFile>
    <outputDirectory>${project.reporting.outputDirectory}/code-coverage</outputDirectory>
    <propertyName>jacocoArgLine</propertyName>
    <classDumpDir>${project.build.outputDirectory}</classDumpDir>
  </configuration>
  <executions>
    <execution>
      <id>prepare-jacoco-agent</id>
      <goals>
          <goal>prepare-agent</goal>
      </goals>
    </execution>
    <execution>
      <id>post-integration-test</id>
      <phase>post-integration-test</phase>
      <goals>
        <goal>report</goal>
      </goals>
    </execution>
  </executions>
</plugin>

请注意,检测到的类来自所有依赖项,因此需要一些过滤以缩小报告范围。参见:https://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html

答案 2 :(得分:1)

我有类似的项目结构-主代码在一个模块中,并且在注释器中进行测试-并在jacoco报告中遇到了类似的问题。

我的解决方案1 ​​

只需/classesmaven-resources-plugin文件夹复制到测试模块即可。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
       <execution>
         <id>copy-classes-to-test-module</id>
         <goals>
             <goal>testResources</goal>
         </goals>
         <configuration>
             <resources>
                 <resource>
                     <directory>${project.basedir}/../main-module/target/classes</directory>
                 </resource>
             </resources>
             <outputDirectory>
                    ${project.build.outputDirectory}
             </outputDirectory>
          </configuration>
        </execution>
     </executions>
</plugin>

但是,如果您的代码包含lambda,匿名类等,则结果报告可能不会涵盖某些类,因为由于运行prepare-agent的不同,结果报告将是不同的类。

我的解决方案2:

使用report-aggregate目标。

在父POM中,我有这样的配置:

<plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.3</version>
        <configuration>
            <append>true</append>
        </configuration>
        <executions>
            <execution>
                <id>prepare-agent</id>
                <goals>
                    <goal>prepare-agent</goal>
                </goals>
            </execution>
        </executions>
</plugin>

测试模块的POM包含以下几行:

        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>report</id>
                    <phase>test</phase>
                    <goals>
                        <goal>report-aggregate</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

请记住,依赖性范围对于report-aggregate目标(jacoco docs)很重要。如果您的测试模块只有测试范围的依赖项,您将得到一个空报告。因此,您应该将范围设置为编译,运行时或为要在报告中看到的那些工件提供。例如:

    <dependency>
        <groupId>my.project</groupId>
        <artifactId>main-module-classes</artifactId>
        <version>${project.version}</version>
        <scope>provided</scope>
    </dependency>

答案 3 :(得分:0)

您可以使用目标jacoco:report-aggregate,该目标正是为在单独的测试模块中创建覆盖率报告而设计的。

这里是一个示例:

project
└─ module      ⇦ module with sources
└─ module-test ⇦ module with tests

然后您要做的就是在“模块测试”的pom.xml中使用此目标:

    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.version}</version>
                <executions>
                    <execution>
                        <id>jacoco-report-aggregate</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>report-aggregate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

也要小心docs中提到的在依赖项中使用的范围。