10

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

4

4 回答 4

10

创建一个监听器类

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())
  }
}

最后用你的实现的全名创建org.spockframework.runtime.extension.IGlobalExtension你的文件(如果你使用的是Maven,META-INF/services directory通常它会在下面),例如src/test/resourcesIGlobalExtension

com.example.tests.GlobalSpecExtension
于 2013-05-07T14:20:49.000 回答
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() 将被调用。

于 2013-12-06T13:16:52.673 回答
3

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

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

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

于 2013-05-07T14:08:02.370 回答
0

我无法对 user3074543 的回答进行投票或评论,但它比创建扩展更简单。我要轻松。所以我缩短了 user*'s a little (我不是指 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()
    }
}
于 2015-02-13T01:31:59.683 回答