Geb测试中如何在cleanup块执行前、then块后运行失败截图逻辑
解决方案
你当前使用的AbstractRunListener回调时机为整个测试方法(包含cleanup块)执行完成后,因此会出现截图晚于页面清理的问题,可通过以下两种方案实现then块执行完成后、cleanup块执行前的失败截图逻辑:
方案1:基类统一封装(改动最小,适合快速落地)
所有测试用例继承统一的测试基类,在基类中使用Spock原生的@BeforeCleanup注解实现前置逻辑,该注解标注的方法会优先于用户自定义的cleanup块执行:
abstract class BaseSpec extends Specification { @BeforeCleanup def captureScreenshotOnFailure() { // 判断当前测试用例是否执行失败 if (specificationContext.currentIteration.executionResult.failures) { // 执行截图逻辑 captureScreenshot() } } private void captureScreenshot() { // 写入你原有的截图实现代码 } }
仅需将所有现有测试用例的继承类从Specification改为BaseSpec即可,原有cleanup块逻辑不需要任何修改。
方案2:全局扩展实现(无需修改现有测试用例)
如果不想调整现有测试用例的继承关系,可以通过Spock全局扩展机制实现全量用例的自动适配:
- 实现测试执行拦截器
import org.spockframework.runtime.extension.IInvocationInterceptor import org.spockframework.runtime.extension.IMethodInvocation class FailureScreenshotInterceptor implements IInvocationInterceptor { @Override void intercept(IMethodInvocation invocation) throws Throwable { try { // 先执行测试用例的given/when/then逻辑 invocation.proceed() } catch (Throwable t) { // 测试失败时先截图 captureScreenshot() // 抛出异常保证后续cleanup逻辑正常执行 throw t } } private void captureScreenshot() { // 写入你原有的截图实现代码 } }
- 实现全局扩展注册类
import org.spockframework.runtime.extension.IGlobalExtension import org.spockframework.runtime.model.SpecInfo class GlobalScreenshotExtension implements IGlobalExtension { @Override void visitSpec(SpecInfo spec) { // 给所有测试用例的测试方法添加失败拦截逻辑 spec.allFeatures.each { feature -> feature.addInterceptor(new FailureScreenshotInterceptor()) } } }
- 注册全局扩展
在项目的resources/META-INF/services目录下创建名为org.spockframework.runtime.extension.IGlobalExtension的文件,文件内容填写你实现的GlobalScreenshotExtension的全限定类名即可,无需修改任何现有测试用例代码。
内容的提问来源于stack exchange,提问作者Kanti
相关产品推荐
相关产品推荐

