8

我有一组使用SpringJUnit4ClassRunner. 我正在尝试使用 maven surefire 并行运行这些。但是,我注意到代码在进入同步块之前是阻塞的CacheAwareContextLoaderDelegate.loadContext()

有没有办法绕过这个缓存?我试过这样做,但似乎有更多的共享状态而不仅仅是缓存本身,因为我的应用程序在 Spring 代码中死锁了。或者可以通过某种方式在映射键而不是整个映射上同步来使同步更加细粒度?

我并行化测试的动机是双重的:

  1. 在一些测试中,我用模拟替换了 bean。由于 mock 本质上是有状态的,因此我必须为每个使用@DirtiesContext.
  2. 在其他测试中,我只想部署 Jersey 资源的一个子集。为此,我指定了 Spring 配置类的一个子集。由于 Spring 将MergedContextConfiguration用作上下文缓存中的键,因此这些测试将无法共享 ApplicationContexts。
4

2 回答 2

5

如果您禁用并行测试执行,您的测试套件可能会获得更好的周转时间。在 Spring 参考文档的测试章节中,有一段关于上下文缓存

一旦 TestContext 框架为测试加载了 ApplicationContext(或 WebApplicationContext),该上下文将被缓存并重用于在同一测试套件中声明相同唯一上下文配置的所有后续测试。

为什么要这样实现?

这意味着加载应用程序上下文的设置成本只发生一次(每个测试套件),随后的测试执行速度要快得多。

缓存是如何工作的?

Spring TestContext 框架将应用程序上下文存储在静态缓存中。这意味着上下文实际上存储在静态变量中。换句话说,如果测试在不同的进程中执行,静态缓存将在每次测试执行之间被清除,这将有效地禁用缓存机制。

要从缓存机制中受益,所有测试都必须在同一进程或测试套件中运行。这可以通过在 IDE 中作为一个组执行所有测试来实现。同样,在使用构建框架(如 Ant、Maven 或 Gradle)执行测试时,确保构建框架不会在测试之间分叉很重要。例如,如果 Maven Surefire 插件的 forkMode 设置为 always 或 pertest,TestContext 框架将无法缓存测试类之间的应用程序上下文,构建过程将因此运行速度明显变慢。

于 2013-05-16T05:04:13.847 回答
0

我能想到的一件简单的事情是使用@DirtiesContext

于 2013-05-16T04:29:19.117 回答