【问题标题】:Jacoco + JUnit 5.0 DynamicTest not workingJacoco + JUnit 5.0 DynamicTest 不工作
【发布时间】:2018-11-24 09:32:33
【问题描述】:

我正在尝试使用 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】:

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

    jacoco-maven-plugin:report 不会在测试中显示覆盖率,它会显示测试目标的覆盖率 - 在您的情况下,目标似乎是 Status 类,其定义完全不存在。对于未来,我强烈建议阅读https://stackoverflow.com/help/mcve 并遵循其建议,尤其是关于“完成”的部分:

    确保包含重现问题所需的所有信息


    关于“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;
      }
    
    }
    

    不知道你为什么需要systemPropertyVariablesjacoco-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 看起来像:

    我认为没有执行测试的原因在于default value of includes of 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 匹配第二,但我将把验证作为一个小练习。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-19
      • 1970-01-01
      • 2023-03-19
      相关资源
      最近更新 更多