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

Reply via email to