Jacoco + JUnit 5.0 DynamicTest 不工作

问题描述 投票:0回答:1

我正在尝试使用 Jacoco 与 JUnit 5 和 Spring Boot 生成代码覆盖率报告。我正在尝试使用 JUnit 5 的 DynamicTest 功能。它运行成功,但 jacoco 生成的测试覆盖率报告中未涵盖动态测试。Jacoco 目前是否未涵盖 JUnit 5 动态测试?

这是代码:

    @RunWith(JUnitPlatform.class)
    @SelectPackages("com.troll.jpt.abc.model")
    @SelectClasses({Status.class})
    public class DynamicModelTester {

    private Status status;

    @BeforeEach
    public void setUp() {
        status = new Status();
    }

    @TestFactory
    public Stream<DynamicTest> checkDynamicTestsFromStream() {

        List<String> input = Arrays.asList("abc");
        List<String> output = Arrays.asList("abc");

        status.setCode(input.get(0));

        return input.stream().map(str ->  DynamicTest.dynamicTest("status test", () -> {
            assertEquals(output.get(0), status.getCode());
        }));
    }
}

我使用的 jacoco 插件如下:

    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.2-SNAPSHOT</version>
        <executions>
            <execution>
                <id>prepare-agent</id>
                <goals>
                    <goal>prepare-agent</goal>
                </goals>
            </execution>
            <execution>
                <id>report</id>
                <phase>prepare-package</phase>
                <goals>
                    <goal>report</goal>
                </goals>
            </execution>
            <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>target/jacoco.exec</dataFile>
                    <!-- Sets the output directory for the code coverage report. -->
                    <outputDirectory>target/jacoco-ut</outputDirectory>
                </configuration>
            </execution>
        </executions>
        <configuration>
            <systemPropertyVariables>
                <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
            </systemPropertyVariables>
        </configuration>
    </plugin>
spring-boot jacoco junit5 jacoco-maven-plugin
1个回答
3
投票

它运行成功,但动态测试未包含在 jacoco 生成的测试覆盖率报告中。

jacoco-maven-plugin:report
不显示测试中的覆盖范围,它显示测试目标的覆盖范围 - 在您的情况下,目标似乎是类
Status
,其定义完全不存在。

对“JaCoCo 是否支持 JUnit 5 动态测试?”等问题的通用回答是:JaCoCo 记录代码的执行方式独立于其执行方式 - 通过 JUnit 4 或 JUnit 5,甚至手动或任何其他执行方式。

以及诸如“为什么某些代码未标记为已覆盖?”之类的问题的通用答案是:确保代码实际执行,在自动测试的情况下,这意味着 - 确保这些测试实际执行

但是让我们尝试一下 JUnit 5 动态测试。如果没有

src/main/java/Status.java
我会假设它是这样的

public class Status {

  private String code;

  public void setCode(String code) {
    this.code = code;
  }

  public String getCode() {
    return code;
  }

}

不知道为什么你需要

systemPropertyVariables
jacoco-maven-plugin
的快照版本、
report
的多次执行以及
dataFile
及其默认值的冗余规范,因此还将假设在稍微清理后完整的
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>

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

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.2.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>5.2.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.vintage</groupId>
      <artifactId>junit-vintage-engine</artifactId>
      <version>5.2.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.platform</groupId>
      <artifactId>junit-platform-runner</artifactId>
      <version>1.2.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <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>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.21.0</version>
      </plugin>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.1</version>
        <configuration>
          <outputDirectory>target/jacoco-ut</outputDirectory>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>prepare-agent</goal>
              <goal>report</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>

放置后

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.runner.RunWith;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import static org.junit.Assert.assertEquals;

@RunWith(JUnitPlatform.class)
@SelectPackages("com.troll.jpt.abc.model")
@SelectClasses({Status.class})
public class DynamicModelTester {

  private Status status;

  @BeforeEach
  public void setUp() {
    status = new Status();
  }

  @TestFactory
  public Stream<DynamicTest> dynamicTestsFromStream() {
    List<String> input = Arrays.asList("abc");
    List<String> output = Arrays.asList("abc");

    status.setCode(input.get(0));

    return input.stream().map(str ->  DynamicTest.dynamicTest("status test", () -> {
      assertEquals(output.get(0), status.getCode());
    }));
  }

}

进入

src/test/java/DynamicModelTester.java
并执行
mvn clean verify

[INFO] --- maven-surefire-plugin:2.21.0:test (default-test) @ example ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ example ---
[INFO] Building jar: /private/tmp/jacoco/target/example-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- jacoco-maven-plugin:0.8.1:report (default) @ example ---
[INFO] Skipping JaCoCo execution due to missing execution data file.

最后一行非常可疑,并且缺乏

maven-surefire-plugin
执行的测试数量以及缺乏
target/surefire-reports/

让我们将

DynamicModelTester
重命名为
DynamicModelTest
并再次执行
mvn clean verify

[INFO] --- maven-surefire-plugin:2.21.0:test (default-test) @ example ---
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running DynamicModelTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.023 s - in DynamicModelTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ example ---
[INFO] Building jar: /private/tmp/jacoco/target/example-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- jacoco-maven-plugin:0.8.1:report (default) @ example ---
[INFO] Loading execution data file /private/tmp/jacoco/target/jacoco.exec
[INFO] Analyzed bundle 'example' with 1 classes

与之前的尝试相比,这次执行了测试。覆盖率报告

target/jacoco-ut/default/Status.html
看起来像:

我认为测试没有执行的原因在于includes

默认值
maven-surefire-plugin
:

指定测试(按模式)的元素列表 应包含在测试中。当未指定时和测试时 不指定参数,默认包含

<includes>
    <include>**/Test*.java</include>
    <include>**/*Test.java</include>
    <include>**/*Tests.java</include>
    <include>**/*TestCase.java</include>
</includes>

DynamicModelTester.java
与这些模式中的任何一个都不匹配,而
DynamicModelTest.java
匹配第二个,但我将对此进行验证作为一个小练习。

© www.soinside.com 2019 - 2024. All rights reserved.