如何在Spock框架的每个when步骤自动执行takeScreen()
如何在Spock框架的每个when步骤自动执行takeScreen()?
这个需求其实用Spock的扩展机制就能完美解决,不用再手动重复写takeScreen()啦!我给你两种实用的实现方式:
方式一:自定义Spock扩展(推荐)
Spock支持通过扩展拦截测试的各个执行阶段,我们可以写一个扩展,让它自动在每个when块执行完成后调用截图方法。
第一步:编写扩展拦截器
创建一个拦截器类,用来监听when块的执行:
import org.spockframework.runtime.extension.AbstractMethodInterceptor import org.spockframework.runtime.extension.IMethodInvocation import org.spockframework.runtime.model.MethodKind class AutoTakeScreenExtension extends AbstractMethodInterceptor { @Override void interceptBlockExecution(IMethodInvocation invocation) { // 判断当前执行的是不是when块 if (invocation.method.kind == MethodKind.WHEN) { try { // 先执行when块里的业务逻辑 invocation.proceed() // 执行完后自动调用截图方法 invocation.instance.takeScreen() } catch (Exception e) { // 即使when块执行出错,也截图留存(方便排查问题) invocation.instance.takeScreen() throw e } } else { // 其他类型的块(比如then、given)正常执行 invocation.proceed() } } }
第二步:注册扩展
你可以选择局部生效或者全局生效:
局部生效(用注解)
先定义一个注解来绑定扩展:
import org.spockframework.runtime.extension.ExtensionAnnotation import java.lang.annotation.ElementType import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy import java.lang.annotation.Target @Retention(RetentionPolicy.RUNTIME) @Target([ElementType.TYPE, ElementType.METHOD]) @ExtensionAnnotation(AutoTakeScreenExtension) @interface AutoTakeScreen {}
然后在你的测试类或者单个测试方法上加上这个注解就可以了:
@AutoTakeScreen class YourTestSpec extends Specification { def "doSomeAction"() { when: doSmth() // 不用手动写takeScreen()了! then: at SomePage when: doAction() // 这里也不用写 then: at SomePage } def takeScreen() { // 你的截图逻辑代码 } }
全局生效(所有测试自动应用)
如果想让所有Spock测试都自动执行截图,只需要在项目的META-INF/services目录下创建一个名为org.spockframework.runtime.extension.IGlobalExtension的文件,里面写上你的扩展类全路径:
com.yourpackage.AutoTakeScreenExtension
这样所有测试类都会自动应用这个扩展,不用加注解。
补充说明
- 上面的扩展会在
when块执行完成后无论成功还是失败都截图,如果只想要成功时截图,删掉catch块里的invocation.instance.takeScreen()即可。 - 确保
takeScreen()方法是测试类的public或者protected方法,这样扩展才能正常调用到它。
内容的提问来源于stack exchange,提问作者user8537525
相关产品推荐
相关产品推荐

