2013-05-07 198 views
7

我有一个运行在SpringJUnit4ClassRunner上的集成测试集合。我试图用maven surefire并行运行这些。但是,我注意到,在进入CacheAwareContextLoaderDelegate.loadContext()中的同步块之前,代码被阻塞。与maven并行运行弹簧测试

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

我对parallelising测试的动机是双重的:

  1. 在一些测试中,我用嘲笑取代豆。由于嘲笑本质上是有状态的,我必须使用@DirtiesContext为每个测试方法构建新的ApplicationContext。
  2. 在其他测试中,我只想部署Jersey资源的一个子集。为此,我指定了Spring配置类的一个子集。由于Spring使用MergedContextConfiguration作为上下文缓存中的关键字,因此这些测试将无法共享ApplicationContext。
+0

我[为此提出了一个错误报告](https://jira.springsource。组织/浏览/ SPR-10536) – hertzsprung 2013-05-07 14:02:28

回答

3

这是可能的,可以得到更好的周转时间将你的测试套装,如果你禁用parallell测试执行。在Spring的参考文档的测试章有一个关于Context caching段:

一旦TestContext框架加载的测试ApplicationContext中(或WebApplicationContext的),这种情况下将被缓存,并为申报所有后续测试重用同一个测试套件中同样独特的上下文配置。

为什么它是这样实现的?

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

缓存如何工作?

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

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

+0

谢谢,我不认为我会在文档中阅读该段落。我已经更新了我的问题来解释我的平行动机。希望[我报告的错误](https://jira.springsource.org/browse/SPR-10536)很快就会得到修复。 – hertzsprung 2013-05-16 18:21:14

+1

@hertzsprung我建议你创建一个单独的模拟应用程序上下文(或测试[profile](http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/)包含模拟),可以被其他测试缓存和重用(如果你重置模拟对象的状态,例如'@ Before'或'@ After',这可能是可能的。我的[博客文章](http://www.jayway.com/2011/12/12/spring-integration-tests-part-ii-using-mock-objects/))。 – matsev 2013-05-16 20:40:49

0

,我能想到的一个容易的事情,使用@DirtiesContext

+1

谢谢,我知道那个注释。它可以清除测试类或测试方法之间的上下文,但是据我所知,并不能避免全局锁定。 – hertzsprung 2013-05-16 17:57:02

+0

准确地说,在我看来,使用@DirtiesContext应该被视为反模式。 – 2017-09-01 07:31:32