在Test::Unit
执行teardown
之前,{{1}}中的ruby单元测试失败的断言后,是否有一些干净而优雅的方法来执行我的代码?
我正在进行一些自动GUI测试,并希望在出现故障后立即截取屏幕截图。
答案 0 :(得分:9)
如果您使用的是1.9,请不要使用Test :: Unit :: TestCase作为基类。对它进行子类化并覆盖#run_test进行救援,获取屏幕截图并重新加注:
class MyAbstractTestCase < Test::Unit::TestCase
def run_test( *args )
super(*args)
rescue
snapshot()
raise
end
end
或者,我认为这实际上是最简洁的方法,你可以使用before_teardown钩子:
class MyTestCase < Test::Unit::TestCase
add_teardown_hook do |tc|
screenshot() unless tc.passed?
end
end
这不适用于1.8的测试/单位,但最小的是1.9。
答案 1 :(得分:3)
你可以扩展Test::Unit::Assertions
来做你喜欢的事情,我认为没有内置的方法可以做到这一点。也许是这样的事情(快速和肮脏):
require 'test/unit'
module Test::Unit::Assertions
def safe_assert(test, msg=nil)
passed = msg.nil? ? assert(test) : assert(test,msg)
ensure
puts 'take screenshot' unless passed
end
end
class MyTest < Test::Unit::TestCase
def setup
puts 'setup'
end
def teardown
puts 'teardown'
end
def test_something
safe_assert true
puts 'before failing assert'
safe_assert false, "message"
puts 'after failing assert'
end
end
输出:
Loaded suite unittest
Started
setup
before failing assert
take screenshot
teardown
F
Finished in 0.001094 seconds.
1) Failure:
test_something(MyTest) [unittest.rb:5]:
message
1 tests, 2 assertions, 1 failures, 0 errors, 0 skips
Test run options: --seed 58428
编辑:您实际上可以通过更简单的方式将参数传递给assert
:
module Test::Unit::Assertions
def safe_assert(*args)
passed = assert(*args)
ensure
puts 'take screenshot' unless passed
end
end
另外,如果您不经常需要此功能,则可以在assert
- begin
- ensure
块中包含标准end
:
class MyTest < Test::Unit::TestCase
def test_something
safe_assert true
puts 'before failing assert'
begin
passed = assert false, "message"
ensure
puts 'take screenshot' unless passed
end
puts 'after failing assert'
end
end
或者您构建了一个方法来确保屏幕截图,如下例所示。这实际上对我来说似乎是最干净的方式:
def screenshot_on_fail
passed = yield
ensure
puts 'take screenshot' unless passed
end
class MyTest < Test::Unit::TestCase
def test_something_else
screenshot_on_fail do
assert true
end
screenshot_on_fail do
assert false, 'message'
end
end
end