使用 JUnit 5,如何在测试实例之间共享“ExtensionContext.Store”中的信息?

Sil*_*rus 6 java junit junit5

我在使用 JUnit 5(5.0 或 5.1)和自定义扩展时遇到了麻烦。

我们正在使用服务加载器加载所有实现,然后修改我们的扩展如何引导。这些实现只能加载一次,所以我正在考虑使用ExtensionContext.Store并将其放置在那里。然后,每个后续的测试实例都会从而Store不是通过服务加载器加载它。

现在,我什至知道分层上下文结构,并且我知道有一些“根”上下文可以通过ExtensionContext.getRoot(). 但是这个“根”上下文(实例JupiterEngineExtensionContext)并不是真正的根——每个测试实例都有不同的上下文。

假设你有FooTestand BarTest,然后打印出getRoot()每个产量:

org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@1f9e9475 org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@6c3708b3

因此尝试从中检索先前存储的信息Store失败。

  • 有这个限制吗?它使之间的界线ClassExtensionContextJupiterEngineExtensionContext相当模糊。
  • 还有另一种方法可以通过扩展全局存储一些信息吗?

这是我尝试与商店合作的(非常)简化版本(基本上删除所有其他信息)。我还添加了一些System.out.print()电话来强调我所看到的。在两个测试类上执行这个扩展会产生我上面描述的结果:

    public class MyExtension implements BeforeAllCallback {

    @Override
    public void beforeAll(ExtensionContext context) throws Exception {
        System.out.println(context.getRoot());
        if (context.getRoot().getStore(Namespace.create(MyExtension.class)).get("someIdentifier", String.class) == null) {
            context.getRoot().getStore(Namespace.create(MyExtension.class)).put("someIdentifier", "SomeFooString");
        } else {
            // this is never executed
            System.out.println("Found it, no need to store anything again!");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:这是一个关于 GH( link )的最小项目,由 运行mvn clean install,它显示了我看到的行为。

Sam*_*nen 5

我只是逐字复制了您的MyExtension内容(即零更改)并运行了FooTestBarTest

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(MyExtension.class)
class FooTest {

    @Test
    void test() {
    }
}
Run Code Online (Sandbox Code Playgroud)

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(MyExtension.class)
class BarTest {

    @Test
    void test() {
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是:

org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@2280cdac
org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@2280cdac
Found it, no need to store anything again!
Run Code Online (Sandbox Code Playgroud)

因此,getRoot()按照记录工作。

为什么您看到两个不同的根的唯一解释是您必须在不同的进程中执行测试。

请记住,根实例ExtensionContext绑定到测试套件的当前执行。

因此,如果您在 IDE 中一个接一个地运行FooTestBarTest实际上会产生两个具有不同根的“测试套件”。如果您将构建工具配置为在测试类之间进行分叉,情况也是如此。

然而,如果您在一个“测试套件”中一起执行两个测试类(例如,通过告诉您的 IDE 在同一包或同一源树中运行所有测试),您将看到有一个根,如输出 I 中所示上面提供了。

但请注意,junit-platform-surefire-provider1.0.3 之前的版本存在一个问题,即提供商为每个测试类启动了 JUnit 平台。即使 Surefire 实际上并未启动新的 JVM 进程,这也会产生分叉的外观。有关详细信息,请参阅https://github.com/junit-team/junit5/pull/1137