Oops... forgot to CC to group. Adrian. Begin forwarded message:
> From: Adrian Howard <[EMAIL PROTECTED]> > Date: Sun Jun 16, 2002 08:25:37 pm Europe/London > To: Michael G Schwern <[EMAIL PROTECTED]> > Subject: Re: Test::Class... comments? > > On Sunday, June 16, 2002, at 09:07 am, Michael G Schwern wrote: > >> On Sun, Jun 16, 2002 at 12:14:59AM +0100, Adrian Howard wrote: >>> 0) Do other people find this vaguely sane? Even <gasp> possibly >>> useful? >> >> Yes! xUnit with a Perl spin is something I've wanted for a long time. > [snip] > > Not just me then. Good :-) > >>> 3) The fact that num_method_tests() uses the class it was called >>> from, >>> rather that the one it was applied to, seems kind of gnarly. However, >>> it did seem the neatest solution to the inheritance problem mentioned >>> in the documentation. How offensive do people find this, and is there >>> a better solution? >> >> I don't quite follow the problem. Could you clarify? > > Rather contrived illustration follows: > > Consider a test method that runs a variable number of test: > > package Base::Test; > use base qw(Test::Class); > use Test::More; > > sub foo : Test(no_plan) { > my $self = shift; > my $objects = $self->{objects}; > isa_ok($_, 'Foo') foreach @$objects; > }; > > Doing: > > Base::Test->new(objects => [Foo->new, Foo->new])->runtests; > > gives us > > ok 1 - The object isa Foo > ok 2 - The object isa Foo > 1..2 > > This works fine, but since having a predetermined number of tests is a > Good Thing we want to let Test::Class know how many tests the method > should run. Since we don't know this until the test object is created we > override new() and set the number of tests then. > > sub new { > my $class = shift; > my $self = $class->SUPER::new(@_); > my $num_objects = @{$self->{objects}}; > $self->num_method_tests('foo', $num_objects); > diag("Base::Test foo in $self now runs $num_objects tests"); > return($self); > }; > > which will give us something like > > # Base::Test foo in Base::Test=HASH(0x11734) now runs 2 tests > 1..2 > ok 1 - The object isa Foo > ok 2 - The object isa Foo > > Now, consider what happens when we extend check_fooness in a subclass: > > package Another::Test; > use base qw(Base::Test); > use Test::More; > > # add one more test to the expected # of tests for foo > sub foo : Test(+1) { > my $self = shift; > $self->SUPER::foo; > ok(1==1, 'pointless test'); > }; > > What we want to happen is for Test::Class to figure out that the total > number of tests that foo() should run in Another::Test is the number of > objects in $self->{objects}, plus one. > > Test::Class does manage this so: > > Another::Test->new(objects => [Foo->new, Foo->new])->runtests; > > will give us > > # Base::Test foo in Another::Test=HASH(0x1174c) now runs 2 tests > 1..3 > ok 1 - The object isa Foo > ok 2 - The object isa Foo > ok 3 - pointless test > > Now, the way I do this at the moment is have num_method_tests() walk up > the callstack until it finds a package that also isa Test::Class (in > this > case Base::Test) and then assume that is the class containing the method > whose # tests it should alter. > > While this works, it just seems a trifle evil. When I coded it my > thoughts went something like "Gosh. That's a greasy hack... must fix > that later". When later eventually came around the other solutions I > came up with seemed even worse. > > I just have a sneaking feeling that there's a more elegant (for some > definition of "elegant") way of handling changing the number of tests > for test methods that will cope with inheritance nicely. > > Make sense? > > Adrian -- Adrian Howard <[EMAIL PROTECTED]> phone: 01929 550720 fax: 0870 131 3033 www.quietstars.com >