cucumber does not go to afterstep when the step failed

来根cucumber。

写在前面

cucumber的AfterStep hook很好用,但是当一个step failed时,Cucumber这个黄瓜就不执行AfterStep了,而如果你需要在每一步后都截图或者每一步都输出日志信息,不管这一步的执行结果是passed还是failed, 那就麻烦了。

不过问题总是有方法可以解决的,我们来看个例子。

正文

Attention:本解答基于cucumber 3.0.0 +, 因为用到的Test Step Finished Event基于3.0.0版本 + 。

给定场景:

每个step执行后都进行全屏截图操作 【No matter the result of the step is passed or failed or whatever】

前提:

解决思路:

在Cucumber中,AfterStep被当作是一个step,所以,如果你的step是failed,后续的step就会skipped,也就是说,AfterStep必然会skipped【弄清楚这一点很重要,就不会白白浪费时间在AfterStep上】,这样如果想要在step failed的情况下,继续运行该scenario后续的step,只能弃用AfterStep,改用Test Step Finished Event

具体步骤:

features/support下,新建文件event.rb, 放入以下内容:

AfterConfiguration do |config|
  config.on_event :test_step_finished do |event|
    step = event.test_step.text
    if step != "AfterStep hook" && step != "Before hook" && step != "After hook"
      file = full_page_screenshot
    end
  end
end

这里,每一步是一个event,所以运行的时候,会按照Before hook ,step, AfterStep hook, After hook来走,鉴于截图只是针对每个step,所以这里筛选掉了其他三类event。

此处的 step取值是event.test_step.text, 这样获取的就是每一步的name,而event.test_step本身是一个step对象,输出的结果不是step的name。

详情可以参考它的documentationTest Step Finished Event,也可以用类似如下的代码在运行时输出其他信息:

这里多提一个:如果想要获取该step的执行结果怎么办?

你一定会想到用event.result, 没错,但是它只输出两个值:✓ , ✗

这就很不友好了,每个step运行后,其实有7种结果:

[:failed, :flaky, :skipped, :undefined, :pending, :passed, :unknown]

event.result是✓ ,它是passed,但是当event.result是✗ ,无法判断到底是failed,还是pending,还是skipped……

这里,你会想到 In Ruby, Everything is an object except block .

调用methods获取event.result的所有methods,然后找到to_sym

使用event.result.to_sym 得到的是符号类型的值, 比如:passed, 想要换成字符, 可以用event.result.to_sym.to_s, 按需择取。

OK,大功告成!此外,你也可以自定义每个event中需要添加的操作,比如截图后上传图片,输出每一步的日志信息,创建实例等等。

The End

参考:

Cucumber does not go to AfterStep if the step is failed!

P.S.
AfterTestStep这个event的documents在17年2月份的时候发出的,估计用的人不多,至少在stack overflow上是没看到,但是用起来没啥问题,感谢 Matt Wynne, 这个event真的很好用。