来根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 3.0.0 +
- 假定你已经定义好了截取全屏的函数full_page_screenshot. 【不知道怎么定义?戳这里找找感觉:capture full page screenshot with capybara】
解决思路:
在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真的很好用。