多次调用 Spock 扩展的启动方法
Spock extension's start method invoked multiple times
我有一堆基于 Spock 和 Geb 的功能测试。我想在执行这些测试之前和之后执行一些操作。所以我创建了全局扩展并向该扩展的 start() 和 stop() 方法添加了所需的功能。但问题是 start/stop 方法被调用 before/after 每个 Spock 规范虽然 Spock 文档 (http://spockframework.org/spock/docs/1.1/all_in_one.html#_global_extensions) 指出:
start() This is called once at the very start of the Spock execution
stop() This is called once at the very end of the Spock execution
是我做错了什么,还是 Spock 文档关于这些方法的行为不正确?
我相信 Spock 在您的测试套件中的每个测试规范开始时都会被调用,因此每次执行
的开始和停止都是 运行
我想您可能想看看在您在问题中链接的同一文档中找到的 Fixture Methods:
http://spockframework.org/spock/docs/1.1/all_in_one.html#_specification
@MantasG Spock 实现了一个 JUnit Runner 并且不控制它的执行方式。全局扩展在 RunContext
中管理,保存在 ThreadLocal
中。如果 surefire 使用多个线程来执行测试,那么这将创建 RunContext
的多个实例,每个实例都有自己的全局扩展列表。如果您使用的是 EmbeddedSpecRunner
那么这也会创建一个新的独立上下文。
This context will stay around until the thread dies. It would be
more accurate to remove the context once the test run has finished,
but the JUnit Runner SPI doesn't provide an adequate hook. That
said, since most environments fork a new JVM for each test run, this
shouldn't be much of a problem in practice.
根据你想做什么,还有其他方法:
- 您可以使用 JUnitRunListener 并使用
testRunStarted
/testRunFinished
挂钩。请注意,您需要通过 surefire 进行注册。
- 如果你真的只想 运行 一次,那么你可以使用故障保护而不是万无一失,并使用前后集成目标。
- 您可以使用静态字段和每个
start
/stop
调用的计数器进行破解,如果计数器为 0 则执行开始操作,一旦计数器达到 0 则执行停止操作. 当然你需要确保这个线程安全。
请注意,surefire 也支持 forking multiple JVMs,这也会影响选项 1 和 3。
我有一堆基于 Spock 和 Geb 的功能测试。我想在执行这些测试之前和之后执行一些操作。所以我创建了全局扩展并向该扩展的 start() 和 stop() 方法添加了所需的功能。但问题是 start/stop 方法被调用 before/after 每个 Spock 规范虽然 Spock 文档 (http://spockframework.org/spock/docs/1.1/all_in_one.html#_global_extensions) 指出:
start() This is called once at the very start of the Spock execution
stop() This is called once at the very end of the Spock execution
是我做错了什么,还是 Spock 文档关于这些方法的行为不正确?
我相信 Spock 在您的测试套件中的每个测试规范开始时都会被调用,因此每次执行
的开始和停止都是 运行我想您可能想看看在您在问题中链接的同一文档中找到的 Fixture Methods: http://spockframework.org/spock/docs/1.1/all_in_one.html#_specification
@MantasG Spock 实现了一个 JUnit Runner 并且不控制它的执行方式。全局扩展在 RunContext
中管理,保存在 ThreadLocal
中。如果 surefire 使用多个线程来执行测试,那么这将创建 RunContext
的多个实例,每个实例都有自己的全局扩展列表。如果您使用的是 EmbeddedSpecRunner
那么这也会创建一个新的独立上下文。
This context will stay around until the thread dies. It would be more accurate to remove the context once the test run has finished, but the JUnit Runner SPI doesn't provide an adequate hook. That said, since most environments fork a new JVM for each test run, this shouldn't be much of a problem in practice.
根据你想做什么,还有其他方法:
- 您可以使用 JUnitRunListener 并使用
testRunStarted
/testRunFinished
挂钩。请注意,您需要通过 surefire 进行注册。 - 如果你真的只想 运行 一次,那么你可以使用故障保护而不是万无一失,并使用前后集成目标。
- 您可以使用静态字段和每个
start
/stop
调用的计数器进行破解,如果计数器为 0 则执行开始操作,一旦计数器达到 0 则执行停止操作. 当然你需要确保这个线程安全。
请注意,surefire 也支持 forking multiple JVMs,这也会影响选项 1 和 3。