1 package Test::Manifest;
8 use vars qw(@EXPORT_OK @EXPORT $VERSION);
11 use File::Spec::Functions qw(catfile);
13 @EXPORT = qw(run_t_manifest);
14 @EXPORT_OK = qw(get_t_files make_test_manifest manifest_name);
18 my $Manifest = catfile( "t", "test_manifest" );
24 sub MY::test_via_harness
26 my($self, $perl, $tests) = @_;
28 return qq|\t$perl "-MTest::Manifest" | .
29 qq|"-e" "run_t_manifest(\$(TEST_VERBOSE), '\$(INST_LIB)', | .
30 qq|'\$(INST_ARCHLIB)', \$(TEST_LEVEL) )"\n|;
35 Test::Manifest - interact with a t/test_manifest file
40 eval "use Test::Manifest";
42 # in the file t/test_manifest, list the tests you want
47 C<Test::Harness> assumes that you want to run all of the F<.t> files in the
48 F<t/> directory in ascii-betical order during C<make test> unless you say
49 otherwise. This leads to some interesting naming schemes for test
50 files to get them in the desired order. This interesting names ossify
51 when they get into source control, and get even more interesting as
54 C<Test::Manifest> overrides the default behaviour by replacing the
55 test_via_harness target in the Makefile. Instead of running at the
56 F<t/*.t> files in ascii-betical order, it looks in the F<t/test_manifest>
57 file to find out which tests you want to run and the order in which
58 you want to run them. It constructs the right value for MakeMaker to
61 In F<t/test_manifest>, simply list the tests that you want to run. Their
62 order in the file is the order in which they run. You can comment
63 lines with a C<#>, just like in Perl, and C<Test::Manifest> will strip
64 leading and trailing whitespace from each line. It also checks that
65 the specified file is actually in the F<t/> directory. If the file does
66 not exist, it does not put its name in the list of test files to run and
67 it will issue a warning.
69 Optionally, you can add a number after the test name in test_manifest
70 to define sets of tests. See C<get_t_files> for more information.
76 =item run_t_manifest( TEST_VERBOSE, INST_LIB, INST_ARCHLIB, TEST_LEVEL )
78 Run all of the files in t/test_manifest through Test::Harness:runtests
79 in the order they appear in the file.
81 eval "use Test::Manifest";
87 require Test::Harness;
90 $Test::Harness::verbose = shift;
93 unshift @INC, map { File::Spec->rel2abs($_) } @_[0,1];
95 my( $level ) = $_[2] || 0;
97 print STDERR "Test::Manifest $VERSION\n"
98 if $Test::Harness::verbose;
100 print STDERR "Level is $level\n"
101 if $Test::Harness::verbose;
103 my @files = get_t_files( $level );
104 print STDERR "Test::Manifest::test_harness found [@files]\n"
105 if $Test::Harness::verbose;
107 Test::Harness::runtests( @files );
110 =item get_t_files( [LEVEL] )
112 In scalar context it returns a single string that you can use directly
113 in WriteMakefile(). In list context it returns a list of the files it
114 found in t/test_manifest.
116 If a t/test_manifest file does not exist, get_t_files() returns
119 get_t_files() warns you if it can't find t/test_manifest, or if
120 entries start with "t/". It skips blank lines, and strips Perl
121 style comments from the file.
123 Each line in t/test_manifest can have three parts: the test name,
124 the test level (a floating point number), and a comment. By default,
127 test_name.t 2 #Run this only for level 2 testing
129 Without an argument, get_t_files() returns all the test files it
130 finds. With an argument that is true (so you can't use 0 as a level)
131 and is a number, it skips tests with a level greater than that
132 argument. You can then define sets of tests and choose a set to
133 run. For instance, you might create a set for end users, but also
134 add on a set for deeper testing for developers.
136 Experimentally, you can include a command to grab test names from
137 another file. The command starts with a C<;> to distinguish it
138 from a true filename. The filename (currently) is relative to the
139 current working directory, unlike the filenames, which are relative
140 to C<t/>. The filenames in the included are still relative to C<t/>.
142 ;include t/file_with_other_test_names.txt
144 Also experimentally, you can stop Test::Manifest from reading filenames
145 with the C<;skip> directive. Test::Harness will skip the filenames up to
146 the C<;unskip> directive (or end of file)
154 To select sets of tests, specify the level in the variable TEST_LEVEL
157 make test # run all tests no matter the level
158 make test TEST_LEVEL=2 # run all tests level 2 and below
164 my $upper_bound = shift;
165 print STDERR "# Test level is $upper_bound\n"
166 if $Test::Harness::verbose;
171 carp( "$Manifest does not exist!" ) unless -e $Manifest;
172 my $result = _load_test_manifest($Manifest, $upper_bound);
173 return unless defined $result;
174 my @tests = @{$result};
176 return wantarray ? @tests : join " ", @tests;
179 # Wrapper for loading test manifest files to support including other files
180 sub _load_test_manifest
182 my $manifest = shift;
183 return unless open my( $fh ), $manifest;
185 my $upper_bound = shift || 0;
190 s/#.*//; s/^\s+//; s/\s+$//;
194 my( $command, $arg ) = split/\s+/, $_, 2;
195 if( ';' eq substr( $command, 0, 1 ) )
197 if( $command eq ';include' )
199 my $result = _include_file( $arg, $., $upper_bound );
200 push @tests, @$result if defined $result;
203 elsif( $command eq ';skip' )
205 while( <$fh> ) { last if m/^;unskip/ }
210 croak( "Unknown directive: $command" );
214 my( $test, $level ) = ( $command, $arg );
215 $level = 1 unless defined $level;
217 next if( $upper_bound and $level > $upper_bound );
219 carp( "Bad value for test [$test] level [$level]\n".
220 "Level should be a floating-point number\n" )
221 unless $level =~ m/^\d+(?:.\d+)?$/;
222 carp( "test file begins with t/ [$test]" ) if m|^t/|;
224 $test = catfile( "t", $test ) if -e catfile( "t", $test );
228 carp( "test file [$test] does not exist! Skipping!" );
232 # Make sure we don't include a test we've already seen
233 next if exists $SeenTest{$test};
235 $SeenTest{$test} = 1;
245 my( $file, $line, $upper_bound ) = @_;
246 print STDERR "# Including file $file at line $line\n"
247 if $Test::Harness::verbose;
251 carp( "$file does not exist" ) ;
255 if( exists $SeenInclude{$file} )
257 carp( "$file already loaded - skipping" ) ;
261 $SeenInclude{$file} = $line;
263 my $result = _load_test_manifest( $file, $upper_bound );
264 return unless defined $result;
270 =item make_test_manifest()
272 Creates the test_manifest file in the t directory by reading
273 the contents of the t directory.
275 TO DO: specify tests in argument lists.
277 TO DO: specify files to skip.
281 sub make_test_manifest()
283 carp( "t/ directory does not exist!" ) unless -d "t";
284 return unless open my( $fh ), "> $Manifest";
287 while( my $file = glob("t/*.t") )
298 =item manifest_name()
300 Returns the name of the test manifest file, relative to t/
311 =head1 SOURCE AVAILABILITY
313 This source is in Github:
315 http://github.com/briandfoy/Test-Manifest/tree/master
319 Matt Vanderpol suggested and supplied a patch for the ;include
324 brian d foy, C<< <bdfoy@cpan.org> >>
326 =head1 COPYRIGHT AND LICENSE
328 Copyright (c) 2002-2009 brian d foy. All rights reserved.
330 This program is free software; you can redistribute it and/or modify
331 it under the same terms as Perl itself.