Test::Unit no tests specified

I browsed the previous thread about this topic – I’m in favor of
Test::Unit determining that a TestCase class has empty tests and calling
that a failure – but in some cases I have superclasses with shared
fixture code and intentionally no test methods of their own, yet
Test::Unit still complains about these:

C:\Temp>more whack.rb
require 'test/unit'

class MyBaseFixture < Test::Unit::TestCase
  def setup
    puts 'setup'
  end
end

class MyTestCase < MyBaseFixture
  def test_me
    assert(1 == 1)
  end
end

C:\Temp>whack.rb
Loaded suite C:/Temp/whack
Started
setup
Fsetup
.
Finished in 0.0 seconds.

  1) Failure!!!
default_test(MyBaseFixture)
[c:/ruby/lib/ruby/site_ruby/1.8/test/unit/testcase.r
b:97]:
No tests were specified

2 tests, 2 assertions, 1 failures, 0 errors

I know I could redesign my stuff to not use inheritence here, but I’d
prefer to only see a failure raised if I have an empty test:

class MyTestCase < …
def test_this
end
end

… but not an empty class …

class MyBaseClass < …
end

Thoughts?

···

Chris
http://clabs.org/blogki
-=-=-=-=-=-=-=-=-=-=-=-=-=-
Free solo piano album (mp3)
http://cministries.org/cstudios/blackandwhite.htm

I browsed the previous thread about this topic – I’m in favor of
Test::Unit determining that a TestCase class has empty tests and calling
that a failure – but in some cases I have superclasses with shared
fixture code and intentionally no test methods of their own, yet
Test::Unit still complains about these:

C:\Temp>more whack.rb
require ‘test/unit’

class MyBaseFixture < Test::Unit::TestCase
def setup
puts ‘setup’
end
end

class MyTestCase < MyBaseFixture
def test_me
assert(1 == 1)
end
end

I know I could redesign my stuff to not use inheritence here, but I’d
prefer to only see a failure raised if I have an empty test:

Another option would be to use inheritence via a module mixin rather than a
concrete superclass:

require ‘test/unit’
module MyBaseFixture
def setup
puts ‘setup’
end
end

class MyTestCase < Test::Unit::TestCase
include MyBaseFixture
def test_me
assert(1 == 1)
end
end

Produces:

$ ruby x.rb
Loaded suite x
Started
setup
.
Finished in 0.095004 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

Otherwise you can just define a null test in your superclass:
def test_dummy; end

which seems to keep it happy. I don’t really see why “no tests” is
considered a failure though. I would equate “no failures” with “success”.

I don’t think an empty test (i.e. one which makes no assertions) should be
considered an error though. It would be quite legitimate to have a method
which performs no tests under certain circumstances dependent on external
criteria:

def test_foo
if @foo_is_relevant
… do some tests
end
end

If that were outlawed, then you would have to jump through hoops to get that
result, e.g. by putting test_foo in a separate module and conditionally
including that module.

Regards,

Brian.

···

On Thu, Jul 17, 2003 at 06:05:26AM +0900, Chris Morris wrote:

I browsed the previous thread about this topic – I’m in favor of
Test::Unit determining that a TestCase class has empty tests and calling
that a failure – but in some cases I have superclasses with shared
fixture code and intentionally no test methods of their own, yet
Test::Unit still complains about these:

I agree this is somewhat aggravating… at this point the best I can suggest
is to do as Brian mentions in [ruby-talk:76195] and pull your common code in
to a module instead of a superclass. Someday I might add support for an
‘abstract test,’ which would alleviate this problem (and others) with
subclassing tests, but for now, modules work OK.

Another option is to override #default_test in your superclass with a
do-nothing method - this will eliminate the failure (but note that it will
eliminate it for all your subclasses, too). If you wanted to be really
fancy, you could even do something like this (not tested):

class MySuperTest < Test::Unit::TestCase
def default_test
super unless(self.class == MySuperTest)
end
end

So there are a few options… I hope one of them works for you.

I know I could redesign my stuff to not use inheritence here, but I’d
prefer to only see a failure raised if I have an empty test:

class MyTestCase < …
def test_this
end
end

Well, I don’t think this is possible (although I know someone will prove me
wrong as soon as I say that). How can one know if a method is empty? There’s
no way I know of to determine it without walking the AST (which would
definitely fall under non-trivial).

Thoughts?

Well, you now have my $0.02. Hope it helps.

Nathaniel

<:((><

···

Chris Morris [mailto:chrismo@clabs.org] wrote:

I know I could redesign my stuff to not use inheritence here, but I’d
prefer to only see a failure raised if I have an empty test:

class MyTestCase < …
def test_this
end
end

Well, I don’t think this is possible (although I know someone will prove
me
wrong as soon as I say that). How can one know if a method is empty?
There’s
no way I know of to determine it without walking the AST (which would
definitely fall under non-trivial).

If you define emptiness as not asserting anything in the method, you could
do above mentioned by resetting a flag (TestCase instance variable) before
calling a test method and check it after the method returns. Asserts would
set this flag and if the flag is not set it would mean that no assert had
been called.

Gennady.

···

----- Original Message -----
From: “Nathaniel Talbott” nathaniel@talbott.ws
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Wednesday, July 16, 2003 3:58 PM
Subject: Re: Test::Unit no tests specified

Another option is to override #default_test in your superclass with a
do-nothing method - this will eliminate the failure (but note that it will
eliminate it for all your subclasses, too). If you wanted to be really
fancy, you could even do something like this (not tested):

class MySuperTest < Test::Unit::TestCase
def default_test
super unless(self.class == MySuperTest)
end
end

···

I didn’t have my Ruby hat on tight enough to think of that. That or the
module option should work fine.


Well, I don’t think this is possible (although I know someone will prove me
wrong as soon as I say that). How can one know if a method is empty? There’s
no way I know of to determine it without walking the AST (which would
definitely fall under non-trivial).

Hadn’t thought of that. DUnit (Delphi) can do this with a cool little
assembler trick – I’d gotten used to the behavior there forgetting how it
was done.

Thanks for the reply.

Chris

I’ve done this with great success. When I worked Dave’s Kata 2 (binary
chop) exercise, I put all his tests in a module called ChopTests. I
then wrote several versions of chop (called chop_iterate,
chop_recursive, etc). The unit tests looked like this …

class TestChopIterative < Test::Unit::TestCase
alias chop chop_iterate
include ChopTests
end

You can see the full example at …
http://onestepback.org/index.cgi/Tech/Programming/Kata/KataTwoVariation1.rdoc

···

On Wed, 2003-07-16 at 18:58, Nathaniel Talbott wrote:

[…] at this point the best I can suggest
is to do as Brian mentions in [ruby-talk:76195] and pull your common code in
to a module instead of a superclass.


– Jim Weirich jweirich@one.net http://onestepback.org

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

True, but I don’t think that’s a good definition of empty test. As Brian
said, I might only conditionally assert, or I might simply have a #flunk in
a test (which won’t get called if the test succeeds).

Nathaniel

<:((><

···

Gennady [mailto:gfb@tonesoft.com] wrote:

If you define emptiness as not asserting anything in the
method, you could do above mentioned by resetting a flag
(TestCase instance variable) before calling a test method and
check it after the method returns. Asserts would set this
flag and if the flag is not set it would mean that no assert
had been called.