lib/Test/Simple.pm Basic utility for writing tests
lib/Test/Simple/Changes Test::Simple changes
lib/Test/Simple/README Test::Simple README
+lib/Test/Simple/t/bad_plan.t Test::Builder plan() test
lib/Test/Simple/t/buffer.t Test::Builder buffering test
lib/Test/Simple/t/Builder.t Test::Builder tests
lib/Test/Simple/t/curr_test.t Test::Builder->curr_test tests
lib/Test/Simple/t/skip.t Test::More test, SKIP tests
lib/Test/Simple/t/skipall.t Test::More test, skip all tests
lib/Test/Simple/t/strays.t Test::Builder stray newline checks
+lib/Test/Simple/t/threads.t Test::Builder thread-safe checks
lib/Test/Simple/t/todo.t Test::More test, TODO tests
lib/Test/Simple/t/undef.t Test::More test, undefs don't cause warnings
lib/Test/Simple/t/useing.t Test::More test, compile test
use strict;
use vars qw($VERSION $CLASS);
-$VERSION = '0.14';
+$VERSION = '0.15';
$CLASS = __PACKAGE__;
my $IsVMS = $^O eq 'VMS';
my($Have_Plan) = 0;
my $Curr_Test = 0;
+# Make Test::Builder thread-safe for ithreads.
+BEGIN {
+ use Config;
+ if( $] >= 5.008 && $Config{useithreads} ) {
+ require threads;
+ require threads::shared;
+ threads::shared->import;
+ share(\$Curr_Test);
+ share(\@Test_Details);
+ share(\@Test_Results);
+ }
+ else {
+ *lock = sub { 0 };
+ }
+}
+
=head1 NAME
return unless $cmd;
+ if( $Have_Plan ) {
+ die sprintf "You tried to plan twice! Second plan at %s line %d\n",
+ ($self->caller)[1,2];
+ }
+
if( $cmd eq 'no_plan' ) {
$self->no_plan;
}
my @args = grep { defined } ($cmd, $arg);
Carp::croak("plan() doesn't understand @args");
}
-
+
+ return 1;
}
=item B<expected_tests>
Carp::croak("You tried to run a test without a plan! Gotta have a plan.");
}
+ lock $Curr_Test;
$Curr_Test++;
-
+
$self->diag(<<ERR) if defined $name and $name =~ /^[\d\s]+$/;
You named your test '$name'. You shouldn't use numbers for your test names.
Very confusing.
Carp::croak("You tried to run tests without a plan! Gotta have a plan.");
}
+ lock($Curr_Test);
$Curr_Test++;
$Test_Results[$Curr_Test-1] = 1;
Carp::croak("You tried to run tests without a plan! Gotta have a plan.");
}
+ lock($Curr_Test);
$Curr_Test++;
$Test_Results[$Curr_Test-1] = 1;
sub current_test {
my($self, $num) = @_;
+ lock($Curr_Test);
if( defined $num ) {
-
unless( $Have_Plan ) {
require Carp;
Carp::croak("Can't change the current test number without a plan!");
sub caller {
my($self, $height) = @_;
$height ||= 0;
-
+
my @caller = CORE::caller($self->level + $height + 1);
return wantarray ? @caller : $caller[0];
}
$Expected_Tests = $Curr_Test;
}
+ # 5.8.0 threads bug. Shared arrays will not be auto-extended
+ # by a slice.
+ $Test_Results[$Expected_Tests-1] = undef
+ unless defined $Test_Results[$Expected_Tests-1];
+
my $num_failed = grep !$_, @Test_Results[0..$Expected_Tests-1];
$num_failed += abs($Expected_Tests - @Test_Results);
$Test->_ending if defined $Test and !$Test->no_ending;
}
+=head1 THREADS
+
+In perl 5.8.0 and later, Test::Builder is thread-safe. The test
+number is shared amongst all threads. This means if one thread sets
+the test number using current_test() they will all be effected.
+
=head1 EXAMPLES
-At this point, Test::Simple and Test::More are your best examples.
+CPAN can provide the best examples. Test::Simple, Test::More,
+Test::Exception and Test::Differences all use Test::Builder.
=head1 SEE ALSO
require Exporter;
use vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS $TODO);
-$VERSION = '0.44';
+$VERSION = '0.45';
@ISA = qw(Exporter);
@EXPORT = qw(ok use_ok require_ok
is isnt like unlike is_deeply
use Some::Module qw(foo bar);
+don't try to do this:
+
+ BEGIN {
+ use_ok('Some::Module');
+
+ ...some code that depends on the use...
+ ...happening at compile time...
+ }
+
+instead, you want:
+
+ BEGIN { use_ok('Some::Module') }
+ BEGIN { ...some code that depends on the use... }
+
=cut
...normal testing code goes here...
}
-This declares a block of tests to skip, $how_many tests there are,
-$why and under what $condition to skip them. An example is the
-easiest way to illustrate:
+This declares a block of tests that might be skipped, $how_many tests
+there are, $why and under what $condition to skip them. An example is
+the easiest way to illustrate:
SKIP: {
- skip "Pigs don't fly here", 2 unless Pigs->can('fly');
+ eval { require HTML::Lint };
- my $pig = Pigs->new;
- $pig->takeoff;
+ skip "HTML::Lint not installed", 2 if $@;
- ok( $pig->altitude > 0, 'Pig is airborne' );
- ok( $pig->airspeed > 0, ' and moving' );
- }
+ my $lint = new HTML::Lint;
+ ok( $lint, "Created object" );
-If pigs cannot fly, the whole block of tests will be skipped
-completely. Test::More will output special ok's which Test::Harness
-interprets as skipped tests. It's important to include $how_many tests
-are in the block so the total number of tests comes out right (unless
-you're using C<no_plan>, in which case you can leave $how_many off if
-you like).
+ $lint->parse( $html );
+ is( scalar $lint->errors, 0, "No errors found in HTML" );
+ }
-It's perfectly safe to nest SKIP blocks.
+If the user does not have HTML::Lint installed, the whole block of
+code I<won't be run at all>. Test::More will output special ok's
+which Test::Harness interprets as skipped, but passing, tests.
+It's important that $how_many accurately reflects the number of tests
+in the SKIP block so the # of tests run will match up with your plan.
-Tests are skipped when you B<never> expect them to B<ever> pass. Like
-an optional module is not installed or the operating system doesn't
-have some feature (like fork() or symlinks) or maybe you need an
-Internet connection and one isn't available.
+It's perfectly safe to nest SKIP blocks. Each SKIP block must have
+the label C<SKIP>, or Test::More can't work its magic.
You don't skip tests which are failing because there's a bug in your
-program. For that you use TODO. Read on.
-
-
-=for _Future
-See L</Why are skip and todo so weird?>
+program, or for which you don't yet have code written. For that you
+use TODO. Read on.
=cut
will run the tests normally, but print out special flags indicating
they are "todo". Test::Harness will interpret failures as being ok.
Should anything succeed, it will report it as an unexpected success.
+You then know the thing you had todo is done and can remove the
+TODO flag.
The nice part about todo tests, as opposed to simply commenting out a
block of tests, is it's like having a programmatic todo list. You know
last TODO;
}
+=item When do I use SKIP vs. TODO?
+
+B<If it's something the user might not be able to do>, use SKIP.
+This includes optional modules that aren't installed, running under
+an OS that doesn't have some feature (like fork() or symlinks), or maybe
+you need an Internet connection and one isn't available.
+
+B<If it's something the programmer hasn't done yet>, use TODO. This
+is for any code you haven't written yet, or bugs you have yet to fix,
+but want to put tests in your testing script (always a good idea).
+
=back
Test::More is B<explicitly> tested all the way back to perl 5.004.
+Test::More is thread-safe for perl 5.8.0 and up.
+
=head1 BUGS and CAVEATS
=over 4
use strict 'vars';
use vars qw($VERSION);
-$VERSION = '0.44';
+$VERSION = '0.45';
use Test::Builder;
Test::Simple is B<explicitly> tested all the way back to perl 5.004.
+Test::Simple is thread-safe in perl 5.8.0 and up.
=head1 HISTORY
Revision history for Perl extension Test::Simple
+0.45 Wed Jun 19 18:41:12 EDT 2002
+ - Andy Lester made the SKIP & TODO docs a bit clearer.
+ - Explicitly disallowing double plans. (RT #553)
+ - Kicking up the minimum version of Test::Harness to one that's
+ fairly bug free.
+ - Made clear a common problem with use_ok and BEGIN blocks.
+ - Arthur Bergman made Test::Builder thread-safe.
+
0.44 Thu Apr 25 00:27:27 EDT 2002
- names containing newlines no longer produce confusing output
(from chromatic)
use Test::Builder;
my $Test = Test::Builder->new;
-$Test->plan( tests => 9 );
+$Test->plan( tests => 7 );
my $default_lvl = $Test->level;
$Test->level(0);
print "ok $test_num - current_test() set\n";
$Test->ok( 1, 'counter still good' );
-
-eval { $Test->plan(7); };
-$Test->like( $@, q{/^plan\(\) doesn't understand 7/}, 'bad plan()' );
-
-eval { $Test->plan(wibble => 7); };
-$Test->like( $@, q{/^plan\(\) doesn't understand wibble 7/}, 'bad plan()' );
--- /dev/null
+#!/usr/bin/perl -w
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't';
+ @INC = '../lib';
+ }
+}
+
+my $test_num = 1;
+# Utility testing functions.
+sub ok ($;$) {
+ my($test, $name) = @_;
+ my $ok = '';
+ $ok .= "not " unless $test;
+ $ok .= "ok $test_num";
+ $ok .= " - $name" if defined $name;
+ $ok .= "\n";
+ print $ok;
+ $test_num++;
+
+ return $test;
+}
+
+
+use Test::Builder;
+my $Test = Test::Builder->new;
+
+print "1..2\n";
+
+eval { $Test->plan(7); };
+ok( $@ =~ /^plan\(\) doesn't understand 7/, 'bad plan()' ) ||
+ print STDERR "# $@";
+
+eval { $Test->plan(wibble => 7); };
+ok( $@ =~ /^plan\(\) doesn't understand wibble 7/, 'bad plan()' ) ||
+ print STDERR "# $@";
+
use Test::More;
-plan tests => 2;
+plan tests => 4;
+eval { plan tests => 4 };
+like( $@, '/^You tried to plan twice!/', 'disallow double plan' );
+eval { plan 'no_plan' };
+like( $@, '/^You tried to plan twice!/', 'disallow chaning plan' );
pass('Just testing plan()');
pass('Testing it some more');
--- /dev/null
+#!/usr/bin/perl -w
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't';
+ @INC = '../lib';
+ }
+}
+
+use Config;
+unless ($Config{'useithreads'}) {
+ print "1..0 # Skip: no threads\n";
+ exit 0;
+}
+
+use strict;
+require threads;
+use Test::Builder;
+
+my $Test = Test::Builder->new;
+$Test->exported_to('main');
+$Test->plan(tests => 6);
+
+for(1..5) {
+ 'threads'->create(sub {
+ $Test->ok(1,"Each of these should app the test number")
+ })->join;
+}
+
+$Test->is_num($Test->current_test(), 5,"Should be five");