【问题标题】:Correctly include jUnit5 @Nested classes when running single class in maven在 maven 中运行单个类时正确包含 jUnit5 @Nested 类
【发布时间】:2021-10-14 23:21:43
【问题描述】:

在 JUnit 5 中执行的 @Nested 类被命令在封闭类中的所有测试之后运行。如果我的目标是运行单个封闭类并且它是嵌套类,我如何使用 maven 强制执行相同的行为?是否有命令行或 pom.xml 修改以使此示例测试通过?

package example;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

public class SomeTopLevelTest {

    private static boolean nestedDone = false;

    @Test
    void test1() {
        Assertions.assertFalse(nestedDone, 
            "Nested classes should execute after the enclosing tests");
    }

    @Nested
    class SomeNestedTest {
        @Test
        void test2() {
            nestedDone = true;
        }
    }

    @AfterAll
    static void recheck() {
        Assertions.assertTrue(nestedDone, "Nested class should be executed");
    }
}

这确实在 IDE 中传递:

但不在命令行中,如果我尝试指定名称:

mvn test -Dtest=example.SomeTopLevelTest

[ERROR] Failures: 
[ERROR]   SomeTopLevelTest.recheck:27 Nested class should be executed ==> expected: <true> but was: <false>


mvn test -Dtest=example.SomeTopLevelTest*
[ERROR] Failures: 
[ERROR]   SomeTopLevelTest.test1:14 Nested classes should execute after the enclosing tests ==> expected: <false> but was: <true>

【问题讨论】:

  • 你能告诉它在哪里定义@Nested classes that are executed in JUnit 5 they are ordered to run AFTER all the tests吗?此外,如果您有单元测试,则不应依赖任何订单,如果需要,您应该检查 Junit Jupiter 中的订单注释......
  • 为什么在测试类中使用静态变量?目的是什么?
  • @khmarbaise “它的定义在哪里?”:我找到的官方消息来源是 stackoverflow.com/a/55482937/1374322 - 值得信赖,因为它来自项目维护者 sam-brannen。 “为什么是静态变量?” - 说明问题。
  • 是的,我知道 Sam Brannon 是谁,但我永远不会依赖这种东西。二、Maven是如何配置的?您使用哪个 Maven 版本?您使用哪个版本的 maven-surefire-plugin?你的 pom 文件是什么样子的?

标签: java maven junit5 maven-surefire-plugin


【解决方案1】:

@Nested 类未执行的问题是一个已知问题,JUnit5Surefire 问题跟踪器都报告了该问题,但截至目前仍未解决。

当前状态(使用 Maven 3.6.3、Junit5 5.7.2、Surefire 2.22.2 到 3.0.0-M5 进行测试):

A.不选择测试

mvn test

按预期执行所有测试类:首先来自封闭类的方法,然后是来自@Nested 类的方法,逐级执行

B.选择测试标准方式

mvn test -Dtest=example.SomeTopLevelTest

这显然会触发使用以下模式的默认肯定excludes

<excludes>
    <exclude>**/*$*</exclude>
</excludes>

如果 A 是一个谜,为什么它不会发生,但是可以通过显式清除排除模式来覆盖此行为:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
            <excludes>
                <exclude/>
            </excludes>
        </configuration>
    </plugin>

不修改 pom.xml 似乎是不可能的。
解决了这个问题中发布的问题,因为嵌套类仍然首先执行。

C.使用带有 -Dtest 参数的通配符

mvn test -Dtest=example.SomeTopLevelTest*

这会显式选择所有嵌套类,但是 - 如问题中所述 - 会导致首先执行嵌套类,因此这不是解决方案。

D.使用包含

mvn test -DtestName=example.SomeTopLevelTest

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <includes>
            <include>${testName}</include>
        </includes>
    </configuration>
</plugin>

显然include 模式的工作方式与-Dtest 参数完全不同,因为这是最终通过问题测试的解决方案。通过此设置,testName 可以是单个类、通配符模式或正则表达式

  • example.SomeTopLevelTest 在单个类中执行所有测试方法
  • example/* - 包示例中的所有测试(包括嵌套),但不包括子包
  • example/** - 包和子包中的所有测试
  • 高级正则表达式,也支持

【讨论】:

  • 感谢includes 的最后一个想法 - 你拯救了我们的一天。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-05
  • 2013-10-26
  • 1970-01-01
相关资源
最近更新 更多