jacoco 简单集成测试解决方案

use*_*343 5 code-coverage maven jacoco

我遵循标准的 Maven 模式,在该模式中我使用单独的模块进行集成测试。该模块有一个包装类,用于执行主要的依赖 jar 项目。

虽然 jar 项目有自己的测试用例,但我对执行这些用例不感兴趣。我想在集成测试执行时查看 jar 项目中的代码覆盖率。简单,没有报告聚合。

God*_*din 5

让我引用http://www.jacoco.org/jacoco/trunk/doc/report-aggregate-mojo.html即使它的名称包含一种“聚合”:

当测试在与被测代码不同的项目中时,这也允许创建覆盖率报告,例如在集成测试的情况下。

咱们试试吧。鉴于jar/src/main/java/example/Example.java

package example;
public class Example {
  // to be covered by unit test
  public void a() {
    System.out.println("a");
  }

  // to be covered by integration test    
  public void b() {
    System.out.println("b");
  }
}
Run Code Online (Sandbox Code Playgroud)

单元测试jar/src/test/java/example/ExampleTest.java

package example;
public class ExampleTest {
  @org.junit.Test
  public void test() {
    new Example().a();
  }
}
Run Code Online (Sandbox Code Playgroud)

集成测试it/src/test/java/example/ExampleITTest.java

package example;
public class ExampleITTest {
  @org.junit.Test
  public void test() {
    new Example().b();
  }
}
Run Code Online (Sandbox Code Playgroud)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>example</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <modules>
    <module>jar</module>
    <module>it</module>
  </modules>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.7.8</version>
        <executions>
          <execution>
            <goals>
              <goal>prepare-agent</goal>
              <goal>report</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>
Run Code Online (Sandbox Code Playgroud)

jar/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>

  <parent>
    <groupId>org.example</groupId>
    <artifactId>example</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>jar</artifactId>

</project>
Run Code Online (Sandbox Code Playgroud)

最后最重要的部分it/pom.xml发生了所有的魔法:

<?xml version="1.0" encoding="UTF-8"?>
<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>

  <parent>
    <groupId>org.example</groupId>
    <artifactId>example</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>it</artifactId>

  <dependencies>
    <dependency>
      <groupId>org.example</groupId>
      <artifactId>jar</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <executions>
          <!--
          "report" goal can't cross boundaries of modules,
          while "report-aggregate" can, so let's use it, however
          by default it will load "jacoco.exec" from this module and from module "jar",
          so let's also change file name for this module to avoid intersection
          -->
          <execution>
            <configuration>
              <destFile>${project.build.directory}/jacoco-it.exec</destFile>
            </configuration>
          </execution>
          <execution>
            <id>it-report</id>
            <phase>verify</phase>
            <goals>
              <goal>report-aggregate</goal>
            </goals>
            <configuration>
              <dataFileIncludes>**/jacoco-it.exec</dataFileIncludes>
              <outputDirectory>${project.reporting.outputDirectory}/jacoco</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
Run Code Online (Sandbox Code Playgroud)

在这样的设置mvn clean verify中将生成两个报告 -jar/target/site/jacoco显示该方法a()被覆盖,并it/target/site/jacoco显示该方法b()被覆盖。


小智 5

我通过添加以下行将 Java 代理附加到应用程序服务器的standalone.sh(启动脚本):

JAVA_OPTS="$JAVA_OPTS -javaagent:/home/jboss/.m2/repository/org/jacoco/org.jacoco.agent/0.7.6.201602180812/org.jacoco.agent-0.7.6.201602180812 -runtime.jar=destfile=/var/lib/jenkins/workspace/HDAP_JaCoCo/jacocoSoapui.exec,includes=*,append=false,output=file"
Run Code Online (Sandbox Code Playgroud)

我已指定目标文件位于 Jenkins 作业的工作区中,该作业运行 JaCoco 代码覆盖率进行单元测试(以便获取与我的覆盖率进行比较的类)。

然后,我指定了两个 exec 文件的路径(一个来自单元测试,另一个是我在上述 Jenkins 作业的记录覆盖率报告部分中为集成测试创建的)。那么我们现在就覆盖了所有测试。

笔记:

  • 需要停止应用程序服务器以将覆盖范围转储到执行文件中。如果您还有其他问题,请告诉我。

  • 当您想要覆盖特定的一组测试时,请确保没有其他任何东西正在运行,因为这将为您提供基本上对应用程序进行的任何调用的覆盖范围。