Skip to content

Commit

Permalink
Swith over to not storing test events.
Browse files Browse the repository at this point in the history
Things which are needed:
1) A way to turn on storage in
   use Test::More
   Test::Builder->create
2) Better docs about how to use (or not use) Test::Builder->results, events and
   Test::More summary and details.

For #198
  • Loading branch information
schwern committed May 25, 2012
1 parent adc2c55 commit b1aa706
Show file tree
Hide file tree
Showing 22 changed files with 105 additions and 58 deletions.
7 changes: 7 additions & 0 deletions Changes
Expand Up @@ -9,6 +9,13 @@ See README and version control log for Test::Builder2 changes.
* Update the resources meta data to point at the correct repository, issues
mailing list and home page.

Incompatible Changes
* The result of each test is no longer stored by default. This keeps
the test framework from consuming more and more memory as tests are
run. Test::Builder->details and Test::Builder->summary will throw
exceptions by default. For most needs, they are replaced with
statistical methods in TB2::History. [github 198]


1.005000_005 Thu Apr 26 15:23:25 PDT 2012
New Features
Expand Down
4 changes: 3 additions & 1 deletion examples/TB2/lib/TB2/NoWarnings.pm
Expand Up @@ -79,10 +79,12 @@ plan is already set, but it doesn't.
sub handle_test_end {
my $self = shift;

$DB::single = 1;

my $warnings = $self->warnings_seen;

$self->builder
->ok( scalar @$warnings, "no warnings" )
->ok( !scalar @$warnings, "no warnings" )
->diag([
warnings => $warnings
]);
Expand Down
12 changes: 9 additions & 3 deletions lib/TB2/History.pm
Expand Up @@ -73,14 +73,14 @@ to grow over the life of the test.
If false, $history will discard events and only keep a summary of
events. L<events> and L<results> will throw an exception if called.
Defaults to true (which will change in a moment).
Defaults to false, events are not stored by default.
=cut

has store_events =>
is => 'ro',
isa => 'Bool',
default => 1
default => 0
;


Expand Down Expand Up @@ -225,7 +225,8 @@ sub subtest_handler {
my $event = shift;

my $subhistory = $self->new(
subtest => $event,
subtest => $event,
store_events => $self->store_events
);

return $subhistory;
Expand Down Expand Up @@ -257,6 +258,8 @@ sub handle_result {
my $self = shift;
my $result = shift;

$DB::single = 1;

$self->result_count( $self->result_count + 1 );
$self->counter( $self->counter + 1 );
$self->_update_statistics($result);
Expand Down Expand Up @@ -658,6 +661,9 @@ sub consume {
croak 'consume() only takes History objects'
unless eval { $old_history->isa("TB2::History") };

croak 'Cannot consume() a History object which has store_events() off'
unless eval { $old_history->store_events };

$self->accept_event($_) for @{ $old_history->events };

return;
Expand Down
1 change: 1 addition & 0 deletions lib/TB2/Tester.pm
Expand Up @@ -68,6 +68,7 @@ sub capture(&) {
my $our_ec = $state->push_coordinator;

$our_ec->clear_formatters;
$our_ec->history( TB2::History->new( store_events => 1 ) );

my($ret, $err) = $CLASS->try(sub { $code->(); 1; });

Expand Down
18 changes: 12 additions & 6 deletions lib/Test/Builder.pm
Expand Up @@ -1741,10 +1741,10 @@ sub current_test {
return $history->counter unless defined $num;

# If the test counter is being pushed forward fill in the details.
my $results = $history->results;
my $result_count = $history->result_count;

if ( $num > @$results ) {
my $last_test_number = @$results ? @$results : 0;
if ( $num > $result_count ) {
my $last_test_number = $result_count ? $result_count : 0;
$history->counter($last_test_number);

for my $test_number ( $last_test_number + 1 .. $num ) {
Expand All @@ -1759,8 +1759,8 @@ sub current_test {
}
}
# If backward, wipe history. Its their funeral.
elsif ( $num < @$results ) {
$#{$results} = $num - 1;
elsif ( $num < $result_count ) {
$history->result_count($num);
}

$history->counter($num);
Expand Down Expand Up @@ -1801,6 +1801,9 @@ This is a logical pass/fail, so todos are passes.
Of course, test #1 is $tests[0], etc...
By default, this method will throw an exception unless Test::Builder has
been configured to store events.
=cut

sub summary {
Expand Down Expand Up @@ -1870,6 +1873,9 @@ result in this structure:
reason => 'insufficient donuts'
};
By default, this test will throw an exception unless Test::Builder has
been configured to store events.
=cut

sub details {
Expand Down Expand Up @@ -2149,7 +2155,7 @@ sub _sanity_check {
my $self = shift;

$self->_whoa( $self->current_test < 0, 'Says here you ran a negative number of tests!' );
$self->_whoa( $self->current_test != @{ $self->history->results },
$self->_whoa( $self->current_test != $self->history->result_count,
'Somehow you got a different number of results than tests ran!' );

return;
Expand Down
4 changes: 3 additions & 1 deletion t/Builder/context.t
Expand Up @@ -9,14 +9,16 @@ use lib 't/lib';
BEGIN { require "t/test.pl" }

use Test::Builder::NoOutput;
use TB2::History;

my $tb = Test::Builder::NoOutput->create;
my $history = TB2::History->new( store_events => 1 );
$tb->test_state->ec->history($history);

my $from_idx = 0;
sub check_events {
my($tb, $line) = @_;

my $results = $tb->history->results;
my $events = $tb->history->events;

my @have = @{$events}[ $from_idx .. $#{$events} ];
Expand Down
10 changes: 9 additions & 1 deletion t/Builder/current_test/test_number.t
Expand Up @@ -3,8 +3,16 @@
# Test that current_test will get the numbering right if no tests
# have yet been run by Test::Builder.

use strict;
use warnings;

use Test::Builder;
$TB = Test::Builder->new;
use TB2::History;

my $TB = Test::Builder->new;
my $history = TB2::History->new( store_events => 1 );
$TB->test_state->ec->history($history);

$TB->no_header(1);
print "ok 1\n";
print "ok 2\n";
Expand Down
8 changes: 7 additions & 1 deletion t/Builder/details.t
Expand Up @@ -7,7 +7,11 @@ use lib 't/lib';

use Test::More;
use Test::Builder;
use TB2::History;

my $Test = Test::Builder->new;
my $history = TB2::History->new( store_events => 1 );
$Test->test_state->ec->history($history);

$Test->plan( tests => 9 );
$Test->level(0);
Expand Down Expand Up @@ -91,7 +95,9 @@ is_deeply( \@details, \@Expected_Details );


# This test has to come last because it thrashes the test details.
{
TODO_SKIP: {
local $TODO = "current_test() going backwards is broken and may be removed";

my $curr_test = $Test->current_test;
$Test->current_test(4);
my @details = $Test->details();
Expand Down
5 changes: 3 additions & 2 deletions t/Builder/reset.t
Expand Up @@ -14,6 +14,7 @@ chdir 't';


use Test::Builder;
use TB2::History;
my $Test = Test::Builder->new;
my $tb = Test::Builder->create;

Expand Down Expand Up @@ -57,8 +58,8 @@ $Test->ok( $tb->use_numbers, , 'use_numbers' );
$Test->ok( !$tb->no_header, , 'no_header' );
$Test->ok( !$tb->no_ending, , 'no_ending' );
$Test->is_num( $tb->current_test, 0, 'current_test' );
$Test->is_num( scalar $tb->summary, 0, 'summary' );
$Test->is_num( scalar $tb->details, 0, 'details' );
$Test->is_num( $tb->history->event_count, 0 );
$Test->is_num( $tb->history->result_count, 0 );
$Test->is_eq( fileno $tb->output,
fileno $Original_Output{output}, 'output' );
$Test->is_eq( fileno $tb->failure_output,
Expand Down
5 changes: 3 additions & 2 deletions t/Builder2/NoWarnings.t
Expand Up @@ -33,9 +33,10 @@ BEGIN { require "t/test.pl" }


# Test the result
plan tests => 2;
plan tests => 3;

# qr/...$/m is broken on Debian etch's 5.8.8
like $builder->formatter->streamer->read("out"), qr/^1\.\.3\n/m, "count correct";
ok $builder->history->results->[2], "no warnings test failed properly";
is $builder->history->result_count, 3, "no warnings test ran";
is $builder->history->fail_count, 1, "no warnings test failed properly";
}
6 changes: 5 additions & 1 deletion t/Builder2/context.t
Expand Up @@ -6,9 +6,13 @@ use warnings;
BEGIN { require 't/test.pl' }

use Test::Builder2;
use TB2::History;

my $tb = Test::Builder2->create;
$tb->test_state->clear_formatters;

$tb->test_state->ec->history(
TB2::History->new( store_events => 1 )
);

my $from_idx = 0;
sub check_events {
Expand Down
5 changes: 1 addition & 4 deletions t/Builder2/ok_starts_a_stream.t
Expand Up @@ -12,10 +12,7 @@ my $tb = Test::Builder2->default;
# ok() starts the stream automatically
{
$tb->ok(1);

my $history = $tb->history;
my $start = grep { $_->event_type eq 'test_start' } @{$history->events};
$tb->ok( $start, "ok issued a test_start" );
$tb->ok( $tb->history->in_test, "ok issued a test_start" );
}

$tb->set_plan( no_plan => 1 );
Expand Down
15 changes: 10 additions & 5 deletions t/Event/TestState.t
Expand Up @@ -22,8 +22,10 @@ note "new() does not work"; {


note "create() and pass through"; {
require TB2::History;
my $state = $CLASS->create(
formatters => []
formatters => [],
history => TB2::History->new( store_events => 1 )
);

is_deeply $state->formatters, [], "create() passes arguments through";
Expand Down Expand Up @@ -94,7 +96,8 @@ note "popping the last coordinator"; {

note "basic subtest"; {
my $state = $CLASS->create(
formatters => []
formatters => [],
history => TB2::History->new( store_events => 1 )
);

note "...starting a subtest";
Expand Down Expand Up @@ -133,7 +136,8 @@ note "basic subtest"; {

note "honor event presets"; {
my $state = $CLASS->create(
formatters => []
formatters => [],
history => TB2::History->new( store_events => 1 )
);

note "...post a subtest with a pre defined depth";
Expand All @@ -156,7 +160,8 @@ note "honor event presets"; {

note "nested subtests"; {
my $state = $CLASS->create(
formatters => []
formatters => [],
history => TB2::History->new( store_events => 1 )
);

my $first_stream_start = TB2::Event::TestStart->new;
Expand Down Expand Up @@ -269,7 +274,7 @@ note "handlers providing their own subtest_handler"; {
my $formatter2 = MyNullFormatter->new;
my $seesall = MyEventCollectorSeesAll->new;
my $collector = MyEventCollector->new;
my $history = MyHistory->new;
my $history = MyHistory->new( store_events => 1 );
my $state = $CLASS->create(
formatters => [$formatter1, $formatter2],
history => $history,
Expand Down
2 changes: 1 addition & 1 deletion t/Event/change_handler.t
Expand Up @@ -22,7 +22,7 @@ note "Set up an early handler"; {
isa => 'TB2::History',
default => sub {
require TB2::History;
return TB2::History->new;
return TB2::History->new( store_events => 1 );
};

sub handle_event {
Expand Down
9 changes: 4 additions & 5 deletions t/History/History.t
Expand Up @@ -26,7 +26,8 @@ my $Fail = TB2::Result->new_result(
{
my $history = new_ok $CLASS;

is_deeply $history->results, [];
is_deeply $history->result_count, 0;
is_deeply $history->event_count, 0;
}


Expand All @@ -38,14 +39,12 @@ my $Fail = TB2::Result->new_result(
);

$ec->post_event( $Pass );
is_deeply $history->results, [$Pass];
is_deeply $history->result_count, 1;

ok $history->can_succeed;

$ec->post_event( $Fail );
is_deeply $history->results, [
$Pass, $Fail
];
is_deeply $history->result_count, 2;

ok !$history->can_succeed;
}
Expand Down
1 change: 0 additions & 1 deletion t/History/HistoryStats.t
Expand Up @@ -32,7 +32,6 @@ note "basic history stats"; {
);

ok!$history->has_results, q{we no not yet have results};
is_deeply $history->results, [], q{blank results set};

$ec->post_event( Pass() );
$ec->post_event( Fail() );
Expand Down
18 changes: 15 additions & 3 deletions t/History/consume.t
Expand Up @@ -10,15 +10,15 @@ use_ok $CLASS;
use TB2::Events;

note "merge history stacks"; {
my $h1 = $CLASS->new;
my $h1 = $CLASS->new( store_events => 1 );

my $pass = TB2::Result->new_result( pass => 1 );
my $fail = TB2::Result->new_result( pass => 0 );

$h1->accept_event($_) for $pass, $pass, $pass;
is $h1->result_count, 3, q{H1 count};

my $h2 = $CLASS->new;
my $h2 = $CLASS->new( store_events => 1 );

$h2->accept_event($_) for $fail, $fail, $fail;
is $h2->result_count, 3, q{H2 count};
Expand All @@ -27,10 +27,22 @@ note "merge history stacks"; {
is $h1->result_count, 6, q{H1 consumed H2};
is $h1->fail_count, 3 , q{H1 picked up the tests from H2 correctly};

my $h3 = $CLASS->new;
my $h3 = $CLASS->new( store_events => 1 );
$h3->accept_event($_) for $pass, $fail;

$h1->consume( $h3 ) for 1..10;

is $h1->result_count, 26, q{consume appends history};
}


note "Try to consume with storage off"; {
my $h1 = $CLASS->new;
my $h2 = $CLASS->new;

ok !eval { $h2->consume( $h1 ); 1 };
is $@, sprintf "Cannot consume() a History object which has store_events() off at %s line %d.\n",
__FILE__, __LINE__-2;
}

done_testing;

0 comments on commit b1aa706

Please sign in to comment.