I just wanted to bring up nested blocks and sub-plans again. I've been hacking 
around in Test::Builder and I've implemented something that works and does 
something that I think is useful. It allows you to write tests that have 
output like

1..5
ok 1 - pass
ok 2 - fail
  1..3 a nested set of tests
  ok 1 - some test
  ok 2 - some other test
    1..2 and another layer
    ok 1 - more tests
    ok 2 - another
  ok 3 - block 'an another layer'
ok 3 - block 'a nested set of tests'
ok 4 - pass
ok 5 - fail

each sub block has it's own plan and the numbering starts from 1. When working 
out the plan for a block, you don't need to think about what happens inside 
it's sub blocks. This makes planning very easy.

When each block finishes it will test that the plan was followed.

Tarball is at

http://www.fergaldaly.com/computer/Test-Builder/

Why would you want to do this? Simple example.

use Test::More tests => 3;

use MyCompany;

is_valid_person(get_manager(), "manager");
is_valid_person(get_ceo(), "ceo");
is_valid_person(get_secretary(), "sec");

sub is_valid_person
{
        my $person = shift;
        my $name = shift;
        my $block = Test::Builder::block("$name valid person?", tests => 17);

        isa($item, "Person", "is a person?");
        like($item->name, qr/^\w+\s+\w$/, "std name");
        # 15 more tests
}

The plan says 3 tests even though there are 3x17 = 34 tests but because the 
is_valid_person tests run in a sub block, they count as just 1 test and if we 
add a new test to that subroutine we just have to update the sub plan, not 
the main one. Also if we call is_valid_person() again, we just increase the 
main plan by 1, not by 17.

So now you can have structured programming in test scripts.

The output above is compatible with Test::Harness because TH ignores lines 
beginning with whitespace. If a test fails inside a sub block, the error will 
propogate all the way to the outermost block so TH will see it. So you can 
test this out without modifying TH, although it would be nice if TH 
understood this format.

This was implemented in 2 stages. First Test::Builder was changed to store 
it's state in a hash instead of package lexicals. Then I added some methods 
to create blocks and track them. You can see the 2 patches at the above URL.

I also knocked out thread safety because it was bugging me with strange 
errors. The whole nested blocks thing will never work nicely with threads 
anyway and since this is just  proof of concept it's not too important for 
now.

Comments? Suggestions? Any chance you would consider this Michael?

F

Reply via email to