My favorites | Sign in
Logo
                
New issue | Search
for
| Advanced search | Search tips
Issue 6: Finding the "top" test function
1 person starred this issue and may be notified of changes. Back to list
Status:  Started
Owner:  schwern
Type-Enhancement
Priority-High
Milestone-Test-Builder2


Sign in to add a comment
 
Reported by schwern, Aug 18, 2008
One of the major problems with Test::Builder is that it does not know which
function is the user-level test function.  Here's a simple example
reimplementing is()

    sub is {
        my($have, $want, $name) = @_;

        my $tb = Test::Builder->new;
        return $tb->ok( $have eq $want, $name ) or
            $tb->diag( <<"END" );
    have: $have
    want: $want
    END

    }

$tb->ok() must look up the stack in order to print out the file and line
number diagnostics.  It also needs this to find the $TODO variable.  It
needs to know that is() is the user-level called function.  Currently it
does this by maintaining how many levels up the stack the "top" is,
$Test::Builder::Level.  This is complicated and buggy and requires careful
tweaking by the test module author.

Test::Builder2 needs a better way to find the top function.

One option is to have test modules declare their test functions to
Test::Builder2.  Something like...

install_test( is => sub {
    my($have, $want, $name) = @_;

    return $TB->ok( $have eq $want, $name ) or
        $TB->diag( <<"END" );
have: $have
want: $want
END

});

This gives Test::Builder total control over entering and leaving each test
routine.  It can remember the top level, eliminating the need for $Level. 
It can perform start and end of test functions, such as die on fail.  And
it can pre-declare a localized Test::Builder object for use in the function
($TB above).

This scheme would seem to solve a number of problems.  The drawback is that
it subverts the normal way to write a Perl module.  Having alternative ways
of declaring a test function may help mitigate this.  Possibilities include:

    # Using attributes
    sub is : Test_Function {
        ...
    }

    # Using an already declared routine
    install_test( "is" );

It's worth considering how this would interact with an autoloader.

A nice bonus is that this allows test functions to use other test
functions.  For example, there is a natural tendency to wrap around
Test::More rather than use Test::Builder.  This will work if the default
for diagnostics is to use the highest test function in the stack.

    use Test::More;

    install_test(is => sub {
        my($have, $want, $name);

        return ok($have eq $want, $name)
          or diag(...);
    });

Comment 1 by schwern, Aug 18, 2008
(No comment was entered for this change.)
Labels: Milestone-Test-Builder2
Comment 2 by schwern, Jan 04, 2009
Test::Builder2::Module implements install_test() and TB2 has a stack containing the
top of the test.  t/Builder2/top.t shows that it can keep track of the top user level
even with multiple wrapped calls.
Status: Started
Owner: schwern
Sign in to add a comment

Hosted by Google Code