som*_*guy 26 ruby unit-testing testunit
我正在与Test :: Unit挣扎.当我想到单元测试时,我想到了每个文件的一个简单测试.但是在Ruby的框架中,我必须改为:
class MyTest < Test::Unit::TestCase
def setup
end
def test_1
end
def test_1
end
end
Run Code Online (Sandbox Code Playgroud)
但是每次调用test_*方法都会运行setup和teardown.这正是我不想要的.相反,我想要一个只为整个类运行一次的设置方法.但我似乎无法在不破坏TestCase初始化的情况下编写自己的initialize().
那可能吗?或者我是否使这无可救药地变得复杂?
Mat*_*lfe 26
正如Hal Fulton的书"The Ruby Way"中所提到的那样.他重写了Test :: Unit的self.suite方法,它允许类中的测试用例作为套件运行.
def self.suite
mysuite = super
def mysuite.run(*args)
MyTest.startup()
super
MyTest.shutdown()
end
mysuite
end
Run Code Online (Sandbox Code Playgroud)
这是一个例子:
class MyTest < Test::Unit::TestCase
class << self
def startup
puts 'runs only once at start'
end
def shutdown
puts 'runs only once at end'
end
def suite
mysuite = super
def mysuite.run(*args)
MyTest.startup()
super
MyTest.shutdown()
end
mysuite
end
end
def setup
puts 'runs before each test'
end
def teardown
puts 'runs after each test'
end
def test_stuff
assert(true)
end
end
Run Code Online (Sandbox Code Playgroud)
Rôm*_*con 10
这就是它应该如何工作!
每个测试应该与其余测试完全隔离,因此每个测试用例都会执行一次setup
和tear_down
方法.但是,有些情况下,您可能希望更多地控制执行流程.然后,您可以在套件中对测试用例进行分组.
在您的情况下,您可以编写如下内容:
require 'test/unit'
require 'test/unit/ui/console/testrunner'
class TestDecorator < Test::Unit::TestSuite
def initialize(test_case_class)
super
self << test_case_class.suite
end
def run(result, &progress_block)
setup_suite
begin
super(result, &progress_block)
ensure
tear_down_suite
end
end
end
class MyTestCase < Test::Unit::TestCase
def test_1
puts "test_1"
assert_equal(1, 1)
end
def test_2
puts "test_2"
assert_equal(2, 2)
end
end
class MySuite < TestDecorator
def setup_suite
puts "setup_suite"
end
def tear_down_suite
puts "tear_down_suite"
end
end
Test::Unit::UI::Console::TestRunner.run(MySuite.new(MyTestCase))
Run Code Online (Sandbox Code Playgroud)
在TestDecorator
定义了一个特殊套件,它提供了一个setup
和tear_down
其前和一组包含的测试用例的运行后只运行一次的方法.
这样做的缺点是你需要告诉Test :: Unit如何在单元中运行测试.如果您的单元包含许多测试用例,并且您只需要其中一个的装饰器,则需要以下内容:
require 'test/unit'
require 'test/unit/ui/console/testrunner'
class TestDecorator < Test::Unit::TestSuite
def initialize(test_case_class)
super
self << test_case_class.suite
end
def run(result, &progress_block)
setup_suite
begin
super(result, &progress_block)
ensure
tear_down_suite
end
end
end
class MyTestCase < Test::Unit::TestCase
def test_1
puts "test_1"
assert_equal(1, 1)
end
def test_2
puts "test_2"
assert_equal(2, 2)
end
end
class MySuite < TestDecorator
def setup_suite
puts "setup_suite"
end
def tear_down_suite
puts "tear_down_suite"
end
end
class AnotherTestCase < Test::Unit::TestCase
def test_a
puts "test_a"
assert_equal("a", "a")
end
end
class Tests
def self.suite
suite = Test::Unit::TestSuite.new
suite << MySuite.new(MyTestCase)
suite << AnotherTestCase.suite
suite
end
end
Test::Unit::UI::Console::TestRunner.run(Tests.suite)
Run Code Online (Sandbox Code Playgroud)
该测试::单位文档文件提供了有关如何套房工作一个很好的解释.
最后,测试单元实现了这一点!活泉! 如果您使用的是v 2.5.2或更高版本,则可以使用:
Test::Unit.at_start do
# initialization stuff here
end
Run Code Online (Sandbox Code Playgroud)
当您开始测试时,这将运行一次.除了在每次测试(设置)之前运行的回调之外,还有在每个测试用例(启动)开始时运行的回调.
http://test-unit.rubyforge.org/test-unit/en/Test/Unit.html#at_start-class_method