14.6 Testing Things That Write to STDOUT and STDERR

One advantage to using the ok( ) functions (and friends) is that they don't write to STDOUT directly, but to a filehandle secretly duplicated from STDOUT when your test script begins. If you don't change STDOUT in your program, of course, this is a moot point. But let's say you wanted to write test a routine that writes something to STDOUT, such as making sure a horse eats properly:

use Test::More 'no_plan';
use_ok 'Horse';
isa_ok(my $trigger = Horse->named('Trigger'), 'Horse');

open STDOUT, ">test.out" or die;
close STDOUT;

open T, "test.out" or die;
my @contents = <T>;
close T;
is(join("", @contents), "Trigger eats hay.\n", "Trigger ate properly");

END { unlink "test.out" }  # clean up after the horses

Note that just before you start testing the eat method, you (re-)open STDOUT to your temporary output file. The output from this method ends up in the test.out file. Bring the contents of that file in and give it to the is( ) function. Even though you've closed STDOUT, the is( ) function can still access the original STDOUT, and thus the test harness sees the proper ok or not ok messages.

If you create temporary files like this, please note that your current directory is the same as the test script (even if you're running make test from the parent directory). Also pick fairly safe cross-platform names if you want people to be able to use and test your module portably.