使用JUnit 5,如何在测试实例之间的“ExtensionContext.Store”中共享信息?
我遇到了JUnit 5(5.0或5.1)和自定义扩展的问题。
我们使用服务加载器加载所有实现,然后修改我们的扩展引导的方式。 这些实现只能加载一次,因此我考虑使用ExtensionContext.Store
并将其放在那里。 然后,每个后续测试实例只从Store
而不是通过服务加载器加载它。
现在,我甚至意识到分层上下文结构,我知道有一些“根”上下文可以通过ExtensionContext.getRoot()
。 但是这个“根”上下文( JupiterEngineExtensionContext
实例)并不是真正的根 – 每个测试实例都有不同的上下文。
假设您有FooTest
和BarTest
,然后为每个产品打印出getRoot()
产量:
org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@1f9e9475
org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@6c3708b3
因此,尝试从Store
检索以前存储的信息失败。
- 是否有此限制? 它使
ClassExtensionContext
和JupiterEngineExtensionContext
之间的界限非常模糊。 - 有没有其他方法通过扩展全局存储一些信息?
这是我尝试使用商店(基本上删除所有其他信息)的(非常)简化版本。 我还添加了一些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
(即零更改)并运行FooTest
和BarTest
。
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
运行FooTest
和BarTest
,那么实际上会产生两个具有不同根的“测试套件”。 如果将构建工具配置为在测试类之间进行分配,情况也是如此。
然而,如果您在一个“测试套件”中一起执行两个测试类(例如,通过告诉您的IDE在同一个包或相同的源树中运行所有测试),那么您将看到输出中有一个根我以上提供。
但请注意,版本1.0.3之前的junit-platform-surefire-provider
存在问题,即提供程序为每个测试类启动了JUnit平台。 即使Surefire实际上没有启动新的JVM进程,这也会出现分叉的现象。 有关详细信息,请参阅https://github.com/junit-team/junit5/pull/1137 。