On Sunday, June 9, 2002, at 02:59 am, chromatic wrote:
> On Saturday 08 June 2002 17:32, Adrian Howard wrote:
>
>> I eventually just bit the bullet and started writing more functional
>> tests. This (of course) had the usual affect of writing more tests ---
>> it made development faster.
>
> What would one of these functional tests look like?
I was probably unclear in my previous message. By "function tests" I
meant a separate script running tests with real objects, not a different
kind of test calls in an existing *.t script.
Make sense?
> I usually end up with a
> few tests per function with names similar to:
>
> - save() should croak() without an 'id' parameter
> - ... and should return false if serialization fails
> - ... or true if it succeeds
>
> I'll probably also have several other tests that don't exercise save()'s
> effective interface. They're not so important for dependency tracking,
> so
> I'll ignore them for now.
>
> My current thinking is that marking the interface tests as special is
> just
> about the only way to track them reliably:
>
> $foo->{_store} = $mock;
> $mock->set_series( 'serialize', 0, 1 );
>
> eval { $foo->save() };
> dlike( @$, qr/No id provided!/, 'save() should croak()...' );
>
> my $result = $foo->save( 77 );
> dok( ! $result, '... and should return false...' );
> dok( $foo->save( 88 ), '... or true...' );
>
> ... where dlike() and dok() are Test::Depend wrappers around
> Test::More's
> like() and ok().
>
> Test::Depend will save the names and results away and compare them at
> the end
> of the test suite's run.
>
> There, that's my handwaving magic in a nutshell. I'm not thrilled with
> the
> dopey names, but haven't a better idea at the moment.
I still think that it'll help less than you think ;-) but, how about
something like:
ok(whatever, 'a non-interface test');
track {
eval { $foo->save() };
like( @$, qr/No id provided!/, 'save() should croak()...' );
my $result = $foo->save( 77 );
ok( ! $result, '... and should return false...' );
ok( $foo->save( 88 ), '... or true...' );
};
ok(whatever, 'another non-interface test');
Since AFAIK every Test::Builder based test boils down to
Test::Builder::ok you could implement like this:
use Test::Builder;
use Hook::LexWrap;
my $Test = Test::Builder->new;
sub track (&) {
my $sub = shift;
# code this evil may encourage young Mr Schwern to
# implement the details method in Test::Builder :-)
my $temp_tracking = wrap 'Test::Builder::ok', post => sub {
my ($ok, $name) = @_[1..2];
my $test = $Test->current_test;
# you would want to stick it in a DB rather than...
$Test->diag(
"tracking test $test in $0 named '$name' which "
. ($ok ? 'passed' : 'failed')
);
};
eval &$sub;
};
This would have the advantage of not having to overwrite all present &
future test functions.
Cheers,
Adrian
--
Adrian Howard <[EMAIL PROTECTED]>
phone: 01929 550720 fax: 0870 131 3033 www.quietstars.com