使用JUnit 5,如何在测试实例之间的“ExtensionContext.Store”中共享信息? [英] With JUnit 5, how to share information in `ExtensionContext.Store` between test instances?

查看:139
本文介绍了使用JUnit 5,如何在测试实例之间的“ExtensionContext.Store”中共享信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am running into trouble with JUnit 5 (5.0 or 5.1) and custom extension.

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

We are using service loader to load all implementations which then modify how our extension is bootstrapped. These implementations can be loaded just once, so I was thinking of using ExtensionContext.Store and placing it there. Every subsequent test instance would then just load it from Store instead of via service loader.

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

Now, I am even aware of the hierarchical context structure and I know that there is some "root" context which you can get through ExtensionContext.getRoot(). But this "root" context (instance of JupiterEngineExtensionContext) isn't really root - there is different one for every test instance.

假设你有 FooTest BarTest ,然后打印出<$ c每个$ c> getRoot()产生:

Say you have FooTest and BarTest, then printing out getRoot() for each of them yields:

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

因此尝试从商店中检索以前存储的信息失败。

And hence trying to retrieve previously stored information from Store fails.


  • 是否有此限制?它使 ClassExtensionContext JupiterEngineExtensionContext 之间的界线非常模糊。

  • 有没有另一种通过扩展程序全局存储某些信息的方法吗?

  • Is having this limitation intended? It makes the borderline between ClassExtensionContext and JupiterEngineExtensionContext pretty blurred.
  • Is there another way to globally store some information via extension?

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

Here is a (very) simplified version of how I tried working with the store (cutting out all other information basically). I also added some System.out.print() calls to underline what I am seeing. Executing this extension on two test classes results in what I described above:

    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 ,显示我看到的行为。

Here is a minimal project on GH(link), run by mvn clean install, which displays the behaviour I see.

推荐答案

我刚复制了你的 MyExtension 逐字(即零更改)并运行 FooTest BarTest

I just copied your MyExtension verbatim (i.e., with zero changes) and ran both FooTest and 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()按照记录的方式工作。

Thus, getRoot() works as documented.

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

The only explanation for why you see two different roots is that you must be executing the tests in different processes.

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

Please keep in mind that the root ExtensionContext instance is bound to the current execution of your test suite.

因此,如果你在IDE中一个接一个地运行 FooTest BarTest ,那实际上会导致两个测试套房有着不同的根源。如果在构建测试类之间将构建工具配置为 fork ,情况也是如此。

So if you run FooTest and BarTest one after the other in an IDE, that will actually result in two "test suites" with different roots. The same is true if you configure your build tool to fork between test classes.

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

Whereas, if you execute both test classes together in a single "test suite" (e.g., by telling your IDE to run all tests in the same package or same source tree) you will then see that there is one root like in the output I provided above.

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

Note, however, that there was an issue with the junit-platform-surefire-provider prior to version 1.0.3, whereby the provider launched the JUnit Platform for each test class. This would give the appearance of forking even though Surefire did not actually start a new JVM process. For details, see https://github.com/junit-team/junit5/pull/1137.

这篇关于使用JUnit 5,如何在测试实例之间的“ExtensionContext.Store”中共享信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆