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

我遇到了JUnit 5(5.0或5.1)和自定义扩展的问题。

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

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

假设您有FooTestBarTest ,然后为每个产品打印出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!"); } } } 

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

我只是简单地复制你的MyExtension (即零更改)并运行FooTestBarTest

 import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(MyExtension.class) class FooTest { @Test void test() { } } 

 import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(MyExtension.class) class BarTest { @Test void test() { } } 

结果是:

 org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@2280cdac org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@2280cdac Found it, no need to store anything again! 

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

您看到两个不同根源的唯一原因是您必须在不同的进程中执行测试。

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

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

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

但请注意,版本1.0.3之前的junit-platform-surefire-provider存在问题,即提供程序为每个测试类启动了JUnit平台。 即使Surefire实际上没有启动新的JVM进程,这也会出现分叉的现象。 有关详细信息,请参阅https://github.com/junit-team/junit5/pull/1137 。