Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Child < Parent < Test::Unit::TestCase

0 views
Skip to first unread message

Brian Adkins

unread,
Oct 11, 2007, 11:29:07 PM10/11/07
to
I just ran into a problem with Test::Unit exhibited by the two files
below and the output of 'ruby tc_child.rb':

--- tc_child.rb ---
require 'tc_parent'

class ChildTest < ParentTest
def test_one
puts 'test_one called'
assert true
end
end
--- tc_child.rb ---

--- tc_parent.rb ---
require "test/unit"

class ParentTest < Test::Unit::TestCase
def setup
puts 'setup called'
end

def teardown
puts 'teardown called'
end
end
--- tc_parent.rb ---

ruby tc_child.rb
Loaded suite tc_child
Started
setup called
test_one called
teardown called
.setup called
Fteardown called

Finished in 0.004709 seconds.

1) Failure:
default_test(ParentTest) [tc_child.rb:4]:
No tests were specified.

2 tests, 2 assertions, 1 failures, 0 errors
---

So apparently it's inadvisable to insert a class between
Test::Unit::TestCase and a 'leaf node' test class. In my case, I ended
up moving the base functionality into a module that I mixed into
tc_child.rb, and this actually worked better for what I'm trying to
accomplish. The flexibility of modules is a great feature of Ruby.

Is there a way to instruct Test::Unit to not attempt to run tests in
intermediate classes in the hierarchy?

Brian Adkins

George

unread,
Oct 11, 2007, 11:49:14 PM10/11/07
to
On 10/12/07, Brian Adkins <lojic...@gmail.com> wrote:
> Is there a way to instruct Test::Unit to not attempt to run tests in
> intermediate classes in the hierarchy?

Hi Brian,

I don't know if it's advisable or not, but one way is to undefine
`default_test'.

require 'test/unit'

class AbstractTestCase < Test::Unit::TestCase
undef_method :default_test
end

class ConcreteTestCase < AbstractTestCase
def test_foo
assert true
end
end

Having said that, unless you really need class inheritance for
something, it's probably cleaner just to #include mixins.

Regards,
George.

Brian Adkins

unread,
Oct 12, 2007, 2:48:57 AM10/12/07
to
On Oct 11, 11:49 pm, George <george.og...@gmail.com> wrote:

> On 10/12/07, Brian Adkins <lojicdot...@gmail.com> wrote:
> > Is there a way to instruct Test::Unit to not attempt to run tests in
> > intermediate classes in the hierarchy?
>
> Hi Brian,
>
> I don't know if it's advisable or not, but one way is to undefine
> `default_test'.
>
> require 'test/unit'
>
> class AbstractTestCase < Test::Unit::TestCase
> undef_method :default_test
> end

Thanks! I just looked through testcase.rb, and your suggestion seems
to be exactly what I was asking for. I'm satisfied with the mixin
approach for my current scenario, but it's nice to know I have an
option for inheritance if the need arises.

Another option is to just hide the class from ObjectSpace :) I did
some experimenting for the heck of it and came up with the following.
It's just a hack for fun, but can anyone come up with a better way of
passing in the class to be hidden to the redefined each_object method
besides the ugly $cloaked global variable? The fact that the
definition is being evaluated in the scope of the metaclass for
ObjectSpace kind of complicates things.

require "test/unit"

class Module
$cloaked = []
def hide_class
$cloaked << self
end
end

class << ObjectSpace
alias orig_each_object each_object
def each_object(klass)
ObjectSpace.orig_each_object(klass) do |obj|
yield obj if !$cloaked.include?(obj)
end
end
end

class ParentTest < Test::Unit::TestCase

hide_class

Brian Adkins

unread,
Oct 12, 2007, 3:20:21 AM10/12/07
to
On Oct 12, 2:48 am, Brian Adkins <lojicdot...@gmail.com> wrote:
> On Oct 11, 11:49 pm, George <george.og...@gmail.com> wrote:
>
> > On 10/12/07, Brian Adkins <lojicdot...@gmail.com> wrote:
> > > Is there a way to instruct Test::Unit to not attempt to run tests in
> > > intermediate classes in the hierarchy?
>
> > Hi Brian,
>
> > I don't know if it's advisable or not, but one way is to undefine
> > `default_test'.
>
> > require 'test/unit'
>
> > class AbstractTestCase < Test::Unit::TestCase
> > undef_method :default_test
> > end
>
> Thanks! I just looked through testcase.rb, and your suggestion seems
> to be exactly what I was asking for. I'm satisfied with the mixin
> approach for my current scenario, but it's nice to know I have an
> option for inheritance if the need arises.
>
> Another option is to just hide the class from ObjectSpace :) I did
> some experimenting for the heck of it and came up with the following.
> It's just a hack for fun, but can anyone come up with a better way of
> passing in the class to be hidden to the redefined each_object method
> besides the ugly $cloaked global variable? The fact that the
> definition is being evaluated in the scope of the metaclass for
> ObjectSpace kind of complicates things.
>
> require "test/unit"
>

Using a Module class variable helps a bit, but it still doesn't feel
right. Of course, that's likely because it's way too late and my brain
shut off a couple hours ago :(

class Module
def hide_class
Module.cloaked << self
end

def Module.cloaked
@@cloaked ||= []
end
end

class << ObjectSpace
alias orig_each_object each_object
def each_object(klass)
ObjectSpace.orig_each_object(klass) do |obj|

yield obj if !Module.cloaked.include?(obj)

0 new messages