File Coverage

blib/lib/Test/AtRuntime.pm
Criterion Covered Total %
statement 27 27 100.0
branch 3 4 75.0
condition n/a
subroutine 7 7 100.0
pod 0 2 0.0
total 37 40 92.5


line stmt bran cond sub pod time code
1             package Test::AtRuntime;
2              
3             =head1 NAME
4              
5             Test::AtRuntime - Put tests in your code and run them as your program runs
6              
7              
8             =head1 SYNOPSIS
9              
10             use Test::AtRuntime 'logfile';
11             use Test::More;
12              
13             sub foo {
14             # This test runs.
15             TEST { pass('foo ran'); }
16             }
17              
18             no Test::AtRuntime;
19              
20             sub bar {
21             # This test is not run.
22             TEST { pass('bar ran') }
23             }
24              
25             foo();
26             bar();
27              
28             =head1 DESCRIPTION
29              
30             Test::AtRuntime lets you use Test::More and other Test::Builder based modules
31             directly in your source code providing a way to test your program as it
32             runs. Similar to the concept of an assertion, except instead of dying
33             when it fails, normal "not ok" output will be seen.
34              
35             =head2 Compiling out
36              
37             Like assertions, they can be turned on or off as needed. Tests are put
38             inside of a TEST block like so:
39              
40             TEST { like( $totally, qr/rad/ ) }
41              
42             C runs these tests. C means these
43             tests will not be run. In fact, they will be completely removed from the
44             program so that performance will not be effected (except some startup
45             performance for the filtering).
46              
47             =head2 Logfile
48              
49             C takes an argument, a logfile to append your tests to.
50             If no logfile is given, tests will be outputed like normal.
51              
52              
53             =head1 CAVEATS
54              
55             Due to what appears to be a bug in Filter::Simple, this won't work as
56             expected:
57              
58             use Test::AtRuntime;
59              
60             ...run tests...
61              
62              
63             no Test::AtRuntime;
64              
65             ...don't run tests...
66              
67             use Test::AtRuntime;
68              
69             ...run tests... <--- BUG
70              
71             Once you stop running tests, they can't be made to run again.
72              
73              
74             =head1 TODO
75              
76             =over 4
77              
78             =item * suppress ok
79              
80             It'll probably be useful to suppress the 'ok' messages so only
81             failures are seen. Then again, "tail -f logfile | grep '^ok '" does a
82             good job of that. Also, Test::Builder doesn't support that yet.
83              
84             =item * honor environment variables
85              
86             Test::AtRuntime should honor the same NDEBUG and PERL_NDEBUG
87             environment variables as Carp::Assert and possibly an additional one
88             just for Test::AtRuntime.
89              
90             =item * stack trace on failure
91              
92             Failing test should be accompanied by a stack trace to help figure out
93             what's going wrong.
94              
95             =back
96              
97              
98             =head1 SEE ALSO
99              
100             Test::More, Carp::Assert, Carp::Assert::More, Test::Inline, Test::Class
101              
102             =cut
103              
104              
105             $VERSION = 0.02;
106              
107 4     4   6495 use Filter::Simple;
  4         127847  
  4         26  
108 4     4   207 use File::Spec;
  4         7  
  4         130  
109 4     4   3976 use Regexp::Common;
  4         10403  
  4         19  
110 4     4   283547 use Test::Builder;
  4         58227  
  4         1564  
111              
112              
113             my $TB = Test::Builder->new;
114             $TB->plan('no_plan');
115             $TB->use_numbers(0);
116             $TB->no_header(0);
117              
118             sub import {
119             my($class, $logfile) = @_;
120             $Testing = $Not_Testing ? 0 : 1;
121             # print STDERR "import: NT $Not_Testing T $Testing\n";
122             set_log($logfile);
123             $Not_Testing = 0;
124             }
125              
126             sub not_testing {
127 3     3 0 9386 my($class, $logfile) = @_;
128 3         8 $Not_Testing = 1;
129             # print STDERR "not_testing\n";
130 3         14 goto &import;
131             }
132              
133             sub set_log {
134 7     7 0 19 my($logfile) = @_;
135              
136 7 100       60 if( defined $logfile ) {
137 1 50       53 open(LOGFILE, ">>$logfile") || die $!;
138 1         5 my $oldfh = select LOGFILE;
139 1         3 $| = 1;
140 1         5 select $oldfh;
141              
142 1         5 $TB->output(\*LOGFILE);
143 1         17 $TB->failure_output(\*LOGFILE);
144 1         25 $TB->todo_output(File::Spec->devnull);
145             }
146             }
147              
148              
149             FILTER_ONLY(
150             executable => sub {
151             $Testing ? s[ \bTEST \s+ ($RE{balanced}{-parens=>'{}'}) ][$1]xg
152             : s[ \bTEST \s+ $RE{balanced}{-parens=>'{}'} ][]xg
153             },
154             # all => sub { print },
155             # qr/^\s*(?:use|no)\s+Test::AtRuntime\b/
156             );
157              
158 4     4   34 no warnings 'redefine';
  4         8  
  4         329  
159             (*unimport, *import) = (\¬_testing, \&import);
160              
161             1;
162              
163