2013-05-07 128 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