【问题标题】:Execute some action when Spock test fails当 Spock 测试失败时执行一些操作
【发布时间】:2013-05-01 11:09:41
【问题描述】:

我想在 Spock 测试失败时执行一些操作。具体来说,截图。可能吗?怎么做?

【问题讨论】:

    标签: testing spock


    【解决方案1】:

    创建一个监听类

    class ExampleListener extends AbstractRunListener {
    
      def void error(ErrorInfo error) {
        println "Actual on error logic"
      }
    }
    

    然后使用为每个规范执行的IGlobalExtension 实现将其添加到每个规范中

    class GlobalSpecExtension implements IGlobalExtension {
    
      @Override
      void visitSpec(SpecInfo specInfo) {
        specInfo.addListener(new ExampleListener())
      }
    }
    

    最后在您的META-INF/services directory 中创建名为org.spockframework.runtime.extension.IGlobalExtension 的文件(如果您使用Maven,它通常位于src/test/resources 下),并带有您的IGlobalExtension 实现的全名,例如

    com.example.tests.GlobalSpecExtension
    

    【讨论】:

    • 在 services 目录中创建一个带有包名的文件的原因是什么?
    • @eddyrokr 文件在那里,所以 spock 知道如何找到类并加载并运行它。它要么是“命名良好的文件”,要么是“扫描整个类路径”,所以几乎每个人都使用命名良好的文件。
    【解决方案2】:

    我无法对 user3074543 的回答进行投票或评论,但它比创建扩展更简单。我要轻松。所以我缩短了 user*'s 一点(我不是指 1-line 方法)。您可以通过记录失败而不是成功来简化逻辑,并使用 done() 帮助程序减少输入。

    class Test extends spock.lang.Specification {
        def fail
        def setup(){ fail = true }
        def done(){ !(fail = false) }
        def cleanup(){ fail && doStuffWhenFail() }
        def 'test things'(){
            expect:
            stuff
            done()
        }
    }
    

    【讨论】:

      【解决方案3】:

      我已经设法做到了:

      class ExampleTest extends GebSpec{
      
          static boolean success = false
      
          def setup(){
              success = false
          }
      
          def cleanup(){
              assert success == true, someAction()
          }
      
          def someAction(){
          }
      
          def "TestCase"(){
              expect:
              /*What you expect here*/
      
              (success = true) != null
          }
      }
      

      在每个测试用例“成功”被 setup() 方法设置为 false 之前。 在每个测试用例的末尾添加“(success = true) != null”语句。因此,只有在测试用例通过时,“成功”才会为真。 在每个测试用例之后,cleanup() 方法将验证“成功”是否为真。如果不是方法 someAction() 将被调用。

      【讨论】:

        【解决方案4】:

        实现这一点的最佳方法是编写一个(全局或注释驱动的)Spock 扩展,实现并注册一个AbstractRunListener。例如,请参阅OptimizeRunOrderExtension。有关如何注册全局扩展,请参阅IGlobalExtension 描述符。

        没有太多关于扩展的文档,因为 API 仍会发生变化。如果你想安全地使用它(并且可以忍受一些限制),你可以实现 JUnit Rule 来代替。

        在这两种情况下您可能会遇到的一个问题是它们不提供对当前规范实例的访问。如果你需要这个,你可能必须同时使用AbstractRunListener(收到失败通知)和IMethodInterceptor(获取规范实例),两者都由同一个扩展注册。 (不应该这么难,但这就是目前的情况。)

        【讨论】:

        • 嗨,彼得!我将如何将这两者结合起来以使驱动程序实例无效并可能重新创建损坏的驱动程序实例?在云测试中,如果我收到WebDriverException: Session [...] was terminated due to TIMEOUT 之类的信息,我可以拦截并在侦听器中记录错误,但无法访问driver 或我可以使其缓存无效的驱动程序工厂。有什么想法吗?
        猜你喜欢
        • 1970-01-01
        • 2022-10-23
        • 1970-01-01
        • 2021-11-16
        • 2014-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-23
        相关资源
        最近更新 更多