【问题标题】:Spring test closes contexts only after all tests in test suite are run只有在测试套件中的所有测试都运行后,Spring 测试才会关闭上下文
【发布时间】:2018-06-11 14:56:35
【问题描述】:

假设我们有如下编写的测试(在单独的文件中):

@SpringBootTest(classes = {SomeBeansProvider.class, FunnyCatBeansProvider.class})
public class CatsTest extends AbstractTestNGSpringContextTests {(...)}

@SpringBootTest(classes = {SomeBeansProvider.class, FunnyCatBeansProvider.class})
public class CatTest2 extends AbstractTestNGSpringContextTests {(...)}

@SpringBootTest(classes = {SomeBeansProvider.class, DogBeansProvider.class})
public class DogsTest extends AbstractTestNGSpringContextTests {(...)}

我不想让事情复杂化,所以让我们暂时假设所有这些测试都打印出类似“Test #no execution completed”的内容。

另外让我们在 SomeBeansProvider.class 中定义这样的方法

@EventListener(ContextClosedEvent.class)
public void onContextClose(final ContextClosedEvent contextClosedEvent) {
   log.info("Context closed.");
} 

如果您执行这些测试(使用 TestNG 运行程序),您将看到类似于以下内容的控制台输出:

  1. 测试 1 执行完成。
  2. 测试 2 执行完成。
  3. 测试 3 执行完成。
  4. 上下文已关闭。
  5. 上下文已关闭。

由于 CatTest 和 CatTest2 具有相同的上下文,因此将为它们创建一个上下文,并为 DogTest 创建一个额外的上下文。

问题是我希望在不再需要上下文后立即关闭它们。我想知道是否可以在执行期间以某种方式自动对测试进行分组,这样就不会同时有多个上下文实例。所以我希望输出看起来像这样:

  1. 测试 1 执行完成。
  2. 测试 2 执行完成。
  3. 上下文已关闭。
  4. 测试 3 执行完成。
  5. 上下文已关闭。

这甚至可能吗?

【问题讨论】:

  • 有什么理由不利用@DirtiesContext 注释?
  • @DirtiesContext 每次都会破坏我的上下文,所以它就像:测试 1 执行完成。上下文关闭。测试 2 执行完成。上下文关闭。测试 3 执行完成。上下文关闭。我想利用 spring 缓存我的 bean。
  • 您希望利用 有时 缓存的 bean。如果您愿意,它也可能会要求您的代码测试结构略有不同,但@DirtiesContext 会让您达到 50%(这就是为什么我也没有将其编码为答案的原因)。
  • 不,你不能,因为没有严格的测试运行顺序。因此,您想要的根本不可能。所有上下文都将被缓存(如果我没记错的话,默认最多 32 个不同的上下文)并将在所有测试运行后被销毁(因为那是测试管理器将被销毁的时间)或者当加载第 33 个上下文时,最旧的将被销毁。
  • 如果您将其发布在单独的帖子中,我会将您的答案标记为已接受。 (Makoto,M.Deinum)。

标签: java spring testng integration-testing spring-test


【解决方案1】:

我们可以在我们的测试用例中使用下面的 Spring 注解来使其在类级别或方法级别的上下文关闭。

@DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)

@DirtiesContext(classMode=ClassMode.AFTER_CLASS)

对于您的场景,您可以这样做,您可以使用 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 在类级别,以及 注释@DirtiesContext(methodMode=ClassMode.AFTER_EACH_TEST_METHOD) 在每个要关闭上下文的测试用例中。并保持 所有相关的测试用例,无论是第一个还是最后一个 升序约定,以便它们连续运行 他们将使用相同的上下文(没有@DirtiesContext)。

【讨论】:

  • 这不会破坏缓存/重用上下文机制吗?
  • 如果我们这样注释,它会破坏它。有什么方法可以将测试用例分组到单独的测试类中
  • 您可以在类级别使用@FixMethodOrder(MethodSorters.JVM(选择您的选项)),并将所有相关的测试用例保留在类的第一个或最后一个,并在每个测试用例级别注释@DirtiesContext .你可以试试这个吗?
  • 也许你可以使用 MethodSorters.NAME_ASCENDING 如上面评论中解释的那样,按照它们可以进入组的顺序重命名测试用例
  • 根据 cmets 更新了答案!
猜你喜欢
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 2017-07-27
  • 2019-07-19
  • 1970-01-01
相关资源
最近更新 更多