I have two unit tests that should share a lot of common tests with slightly different setup methods. If I write something like
我有两个单元测试,它们应该使用稍微不同的设置方法共享许多常见的测试。如果我写
class Abstract < Test::Unit::TestCase
def setup
@field = create
end
def test_1
...
end
end
class Concrete1 < Abstract
def create
SomeClass1.new
end
end
class Concrete2 < Abstract
def create
SomeClass2.new
end
end
then Concrete1 does not seem to inherit the tests from Abstract. Or at least I cannot get them to run in eclipse. If I choose "Run all TestCases" for the file that contains Concrete1 then Abstract is run even though I do not want it to be. If I specify Concrete1 then it does not run any tests at all! If I specify test_1 in Concrete1 then it complains it cannot find it ("uncaught throw :invalid_test (ArgumentError)").
那么具象1似乎没有从抽象中继承测试。或者至少我不能让它们在eclipse中运行。如果我为包含具象1的文件选择“运行所有的测试用例”,那么即使我不希望它运行,抽象也会运行。如果我指定了具体的内容,那么它就不会运行任何测试!如果我在具象1中指定test_1,那么它会报错找不到它(“未捕获的抛出:invalid_test (ArgumentError)”)。
I'm new to Ruby. What am I missing here?
我新Ruby。我错过了什么?
2 个解决方案
#1
7
The issue is that, as far as I can tell, Test::Unit
keeps track of which classes inherit from Test::Unit::TestCase
, and as a result, will only run tests from classes that directly inherit from it.
问题是,就我所知,Test::Unit跟踪哪些类从Test:::Unit::TestCase继承,因此,将只从直接继承它的类运行测试。
The way to work around this is to create a module with the tests you want, and then include that module in the classes that derive from Test::Unit::TestCase
.
解决这个问题的方法是使用您想要的测试创建一个模块,然后将该模块包含到从Test::Unit::TestCase派生的类中。
require 'test/unit'
module TestsToInclude
def test_name
assert(self.class.name.start_with?("Concrete"))
end
end
class Concrete1 < Test::Unit::TestCase
include TestsToInclude
def test_something_bad
assert(false)
end
end
class Concrete2 < Test::Unit::TestCase
include TestsToInclude
def test_something_good
assert(true)
end
end
Output:
输出:
Loaded suite a Started .F.. Finished in 0.027873 seconds. 1) Failure: test_something_bad(Concrete1) [a.rb:13]: <false> is not true. 4 tests, 4 assertions, 1 failures, 0 errors shell returned 1
#2
1
The problem is that Test::Unit::TestCase
explicitly doesn't run tests defined in superclasses by default. In particular, note that TestSuiteCreator
does not run tests unless Test::Unit::TestCase#valid?
returns true (https://github.com/test-unit/test-unit/blob/2.5.5/lib/test/unit/testsuitecreator.rb#L40):
问题是Test::Unit::TestCase显式地不运行默认在超类中定义的测试。特别要注意的是,TestSuiteCreator不会运行测试,除非测试:Unit:::TestCase#有效?返回true(https://github.com/test-unit/test-unit/blob/2.5.5/lib/test/unit/testsuitecreator.rb # L40):
def append_test(suite, test_name)
test = @test_case.new(test_name)
yield(test) if block_given?
suite << test if test.valid?
end
And what determines if a test case is valid? A test case is valid by default if the this class explicitly defined that method, or if the method was defined in a Module
(https://github.com/test-unit/test-unit/blob/2.5.5/lib/test/unit/testcase.rb#L405-L418):
什么决定了一个测试用例是否有效?如果这个类显式定义了该方法,或者在模块中定义了该方法(https://github.com/testunit/test - unit/test/unit/test/unit/testcase.rb# L405-L418),那么测试用例是有效的。
def valid? # :nodoc:
return false unless respond_to?(@method_name)
test_method = method(@method_name)
if @internal_data.have_test_data?
return false unless test_method.arity == 1
else
return false unless test_method.arity <= 0
end
owner = Util::MethodOwnerFinder.find(self, @method_name)
if owner.class != Module and self.class != owner
return false
end
true
end
So basically, if you subclass another unit test class, and you want to run the superclass's unit tests, you can either:
所以基本上,如果你子类化另一个单元测试类,你想运行超类的单元测试,你可以:
- Redefine those test methods in your subclass and have them call your superclass's test method
- 在子类中重新定义这些测试方法,并让它们调用超类的测试方法
- Move all your methods to a module (as explained in the other answer in this thread)
- 将所有方法移动到一个模块(在这个线程的另一个答案中解释)
- Redefine the
valid?
method in your subclass to return true: - 重新定义有效吗?方法在子类中返回true:
def valid? return true end
def有效吗?还真结束
#1
7
The issue is that, as far as I can tell, Test::Unit
keeps track of which classes inherit from Test::Unit::TestCase
, and as a result, will only run tests from classes that directly inherit from it.
问题是,就我所知,Test::Unit跟踪哪些类从Test:::Unit::TestCase继承,因此,将只从直接继承它的类运行测试。
The way to work around this is to create a module with the tests you want, and then include that module in the classes that derive from Test::Unit::TestCase
.
解决这个问题的方法是使用您想要的测试创建一个模块,然后将该模块包含到从Test::Unit::TestCase派生的类中。
require 'test/unit'
module TestsToInclude
def test_name
assert(self.class.name.start_with?("Concrete"))
end
end
class Concrete1 < Test::Unit::TestCase
include TestsToInclude
def test_something_bad
assert(false)
end
end
class Concrete2 < Test::Unit::TestCase
include TestsToInclude
def test_something_good
assert(true)
end
end
Output:
输出:
Loaded suite a Started .F.. Finished in 0.027873 seconds. 1) Failure: test_something_bad(Concrete1) [a.rb:13]: <false> is not true. 4 tests, 4 assertions, 1 failures, 0 errors shell returned 1
#2
1
The problem is that Test::Unit::TestCase
explicitly doesn't run tests defined in superclasses by default. In particular, note that TestSuiteCreator
does not run tests unless Test::Unit::TestCase#valid?
returns true (https://github.com/test-unit/test-unit/blob/2.5.5/lib/test/unit/testsuitecreator.rb#L40):
问题是Test::Unit::TestCase显式地不运行默认在超类中定义的测试。特别要注意的是,TestSuiteCreator不会运行测试,除非测试:Unit:::TestCase#有效?返回true(https://github.com/test-unit/test-unit/blob/2.5.5/lib/test/unit/testsuitecreator.rb # L40):
def append_test(suite, test_name)
test = @test_case.new(test_name)
yield(test) if block_given?
suite << test if test.valid?
end
And what determines if a test case is valid? A test case is valid by default if the this class explicitly defined that method, or if the method was defined in a Module
(https://github.com/test-unit/test-unit/blob/2.5.5/lib/test/unit/testcase.rb#L405-L418):
什么决定了一个测试用例是否有效?如果这个类显式定义了该方法,或者在模块中定义了该方法(https://github.com/testunit/test - unit/test/unit/test/unit/testcase.rb# L405-L418),那么测试用例是有效的。
def valid? # :nodoc:
return false unless respond_to?(@method_name)
test_method = method(@method_name)
if @internal_data.have_test_data?
return false unless test_method.arity == 1
else
return false unless test_method.arity <= 0
end
owner = Util::MethodOwnerFinder.find(self, @method_name)
if owner.class != Module and self.class != owner
return false
end
true
end
So basically, if you subclass another unit test class, and you want to run the superclass's unit tests, you can either:
所以基本上,如果你子类化另一个单元测试类,你想运行超类的单元测试,你可以:
- Redefine those test methods in your subclass and have them call your superclass's test method
- 在子类中重新定义这些测试方法,并让它们调用超类的测试方法
- Move all your methods to a module (as explained in the other answer in this thread)
- 将所有方法移动到一个模块(在这个线程的另一个答案中解释)
- Redefine the
valid?
method in your subclass to return true: - 重新定义有效吗?方法在子类中返回true:
def valid? return true end
def有效吗?还真结束