2017-05-15 33 views
0

我有一堆基於Spock和Geb的功能測試。我想在執行這些測試之前和之後執行一些操作。所以我創建了全局擴展,並添加了必需的功能來啓動該擴展的start()和stop()方法。但問題是,啓動/儘管斯波克文檔(http://spockframework.org/spock/docs/1.1/all_in_one.html#_global_extensions)規定停止方法之前調用/每斯波克規格後:多次調用Spock擴展的啓動方法

的start()這是在斯波克執行的一開始調用一次

STOP()這是在執行斯波克

難道我做錯事或斯波克文檔不正確有關這些方法的行爲的最後調用一次?

+0

可不可以給你如何運行測試的詳細信息。 (Maven/Gradle/...) –

+0

我使用'mvn clean test'命令運行測試。我想這是設計來調用每個規範之前/之後的啓動/停止方法,因爲我使用的Spock報告庫也是作爲全局擴展來實現的,它的工作原理也是一樣的。但也許還有其他方法來實現我所需要的在開始所有測試規範之前以及完成之後調用一些操作? – MantasG

回答

0

@MantasG Spock實現了一個JUnit Runner,並不控制它是如何執行的。全局分機在RunContext中管理,該分機保存在ThreadLocal中。如果surefire使用多個線程來執行測試,那麼這將創建RunContext的多個實例,每個實例都有自己的全局擴展列表。如果您使用的是EmbeddedSpecRunner,那麼這也會創建一個新的獨立環境。

直到線程死亡這方面將保持周圍。一旦測試運行完成, 將更準確地移除上下文,但是JUnit Runner SPI沒有提供足夠的掛鉤。 表示,由於大多數環境爲每次測試運行都分配一個新的JVM,因此在實踐中這應該不是什麼大問題。

取決於你想做的事還有其它的方法是什麼:

  1. 可以使用JUnitRunListener和使用testRunStarted/testRunFinished掛鉤。請注意,您需要通過surefire進行註冊。
  2. 如果您確實只想運行一次,那麼您可以使用故障安全代替surefire,並使用預集成目標和後集成目標。
  3. 您可以使用靜態字段和計數器爲每個start/stop調用破解一些內容,並在計數器爲0時執行開始操作,並在計數器達到0時執行停止操作。當然,您需要將此操作線程安全。

需要注意的是神火也支持forking multiple JVMs而這也將影響選擇1和3

+0

謝謝Leonard,你的回答非常全面。所有建議的選項都可以用來實現我需要的功能,但在我的情況下,這些功能都不起作用,因爲我的Surefire配置中有' false'。在我切換到'reuseForks = true'之後,一切都開始奏效。現在我甚至可以使用Spock擴展來實現我所需要的。 – MantasG