The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Test::Output - Utilities to test STDOUT and STDERR messages.

SYNOPSIS

 use Test::More tests => 4;
 use Test::Output;

 sub writer {
   print "Write out.\n";
   print STDERR "Error out.\n";
 }

 stdout_is(\&writer,"Write out.\n",'Test STDOUT');

 stderr_isnt(\&writer,"No error out.\n",'Test STDERR');

 combined_is(
             \&writer,
             "Write out.\nError out.\n",
             'Test STDOUT & STDERR combined'
            );

 output_is(
           \&writer,
           "Write out.\n",
           "Error out.\n",
           'Test STDOUT & STDERR'
         );

# Use bare blocks.

stdout_is { print "test" } "test", "Test STDOUT";
stderr_isnt { print "bad test" } "test", "Test STDERR";
output_is { print 'STDOUT'; print STDERR 'STDERR' }
  "STDOUT", "STDERR", "Test output";

DESCRIPTION

Test::Output provides a simple interface for testing output sent to STDOUT or STDERR. A number of different utilities are included to try and be as flexible as possible to the tester.

Likewise, Capture::Tiny provides a much more robust capture mechanism without than the original Test::Output::Tie.

TESTS

STDOUT

stdout_is
stdout_isnt
stdout_is  ( $coderef, $expected, 'description' );
stdout_is    { ... } $expected, 'description';
stdout_isnt( $coderef, $expected, 'description' );
stdout_isnt  { ... } $expected, 'description';

stdout_is() captures output sent to STDOUT from $coderef and compares it against $expected. The test passes if equal.

stdout_isnt() passes if STDOUT is not equal to $expected.

stdout_like
stdout_unlike
stdout_like  ( $coderef, qr/$expected/, 'description' );
stdout_like    { ... } qr/$expected/, 'description';
stdout_unlike( $coderef, qr/$expected/, 'description' );
stdout_unlike  { ... } qr/$expected/, 'description';

stdout_like() captures the output sent to STDOUT from $coderef and compares it to the regex in $expected. The test passes if the regex matches.

stdout_unlike() passes if STDOUT does not match the regex.

STDERR

stderr_is
stderr_isnt
stderr_is  ( $coderef, $expected, 'description' );
stderr_is    {... } $expected, 'description';

stderr_isnt( $coderef, $expected, 'description' );
stderr_isnt  {... } $expected, 'description';

stderr_is() is similar to stdout_is, except that it captures STDERR. The test passes if STDERR from $coderef equals $expected.

stderr_isnt() passes if STDERR is not equal to $expected.

stderr_like
stderr_unlike
stderr_like  ( $coderef, qr/$expected/, 'description' );
stderr_like   { ...} qr/$expected/, 'description';
stderr_unlike( $coderef, qr/$expected/, 'description' );
stderr_unlike  { ...} qr/$expected/, 'description';

stderr_like() is similar to stdout_like() except that it compares the regex $expected to STDERR captured from $codref. The test passes if the regex matches.

stderr_unlike() passes if STDERR does not match the regex.

COMBINED OUTPUT

combined_is
combined_isnt
combined_is   ( $coderef, $expected, 'description' );
combined_is   {... } $expected, 'description';
combined_isnt ( $coderef, $expected, 'description' );
combined_isnt {... } $expected, 'description';

combined_is() directs STDERR to STDOUT then captures STDOUT. This is equivalent to UNIXs 2>&1. The test passes if the combined STDOUT and STDERR from $coderef equals $expected.

combined_isnt() passes if combined STDOUT and STDERR are not equal to $expected.

combined_like
combined_unlike
combined_like   ( $coderef, qr/$expected/, 'description' );
combined_like   { ...} qr/$expected/, 'description';
combined_unlike ( $coderef, qr/$expected/, 'description' );
combined_unlike { ...} qr/$expected/, 'description';

combined_like() is similar to combined_is() except that it compares a regex ($expected) to STDOUT and STDERR captured from $codref. The test passes if the regex matches.

combined_unlike() passes if the combined STDOUT and STDERR does not match the regex.

OUTPUT

output_is
output_isnt
output_is  ( $coderef, $expected_stdout, $expected_stderr, 'description' );
output_is    {... } $expected_stdout, $expected_stderr, 'description';
output_isnt( $coderef, $expected_stdout, $expected_stderr, 'description' );
output_isnt  {... } $expected_stdout, $expected_stderr, 'description';

The output_is() function is a combination of the stdout_is() and stderr_is() functions. For example:

output_is(sub {print "foo"; print STDERR "bar";},'foo','bar');

is functionally equivalent to

stdout_is(sub {print "foo";},'foo')
  && stderr_is(sub {print STDERR "bar";},'bar');

except that $coderef is only executed once.

Unlike stdout_is() and stderr_is() which ignore STDERR and STDOUT respectively, output_is() requires both STDOUT and STDERR to match in order to pass. Setting either $expected_stdout or $expected_stderr to undef ignores STDOUT or STDERR respectively.

output_is(sub {print "foo"; print STDERR "bar";},'foo',undef);

is the same as

stdout_is(sub {print "foo";},'foo')

output_isnt() provides the opposite function of output_is(). It is a combination of stdout_isnt() and stderr_isnt().

output_isnt(sub {print "foo"; print STDERR "bar";},'bar','foo');

is functionally equivalent to

stdout_isnt(sub {print "foo";},'bar')
  && stderr_isnt(sub {print STDERR "bar";},'foo');

As with output_is(), setting either $expected_stdout or $expected_stderr to undef ignores the output to that facility.

output_isnt(sub {print "foo"; print STDERR "bar";},undef,'foo');

is the same as

stderr_is(sub {print STDERR "bar";},'foo')
output_like
output_unlike
output_like  ( $coderef, $regex_stdout, $regex_stderr, 'description' );
output_like  { ... } $regex_stdout, $regex_stderr, 'description';
output_unlike( $coderef, $regex_stdout, $regex_stderr, 'description' );
output_unlike { ... } $regex_stdout, $regex_stderr, 'description';

output_like() and output_unlike() follow the same principles as output_is() and output_isnt() except they use a regular expression for matching.

output_like() attempts to match $regex_stdout and $regex_stderr against STDOUT and STDERR produced by $coderef. The test passes if both match.

output_like(sub {print "foo"; print STDERR "bar";},qr/foo/,qr/bar/);

The above test is successful.

Like output_is(), setting either $regex_stdout or $regex_stderr to undef ignores the output to that facility.

output_like(sub {print "foo"; print STDERR "bar";},qr/foo/,undef);

is the same as

stdout_like(sub {print "foo"; print STDERR "bar";},qr/foo/);

output_unlike() test pass if output from $coderef doesn't match $regex_stdout and $regex_stderr.

EXPORTS

By default, all subroutines are exported by default.

  • :stdout - the subs with stdout in the name.

  • :stderr - the subs with stderr in the name.

  • :functions - the subs with _from at the end.

  • :output - the subs with output in the name.

  • :combined - the subs with combined in the name.

  • :tests - everything that outputs TAP

  • :all - everything (which is the same as the default)

FUNCTIONS

stdout_from

my $stdout = stdout_from($coderef)
my $stdout = stdout_from { ... };

stdout_from() executes $coderef and captures STDOUT.

stderr_from

my $stderr = stderr_from($coderef)
my $stderr = stderr_from { ... };

stderr_from() executes $coderef and captures STDERR.

output_from

my ($stdout, $stderr) = output_from($coderef)
my ($stdout, $stderr) = output_from {...};

output_from() executes $coderef one time capturing both STDOUT and STDERR.

combined_from

my $combined = combined_from($coderef);
my $combined = combined_from {...};

combined_from() executes $coderef one time combines STDOUT and STDERR, and captures them. combined_from() is equivalent to using 2>&1 in UNIX.

AUTHOR

Currently maintained by brian d foy, bdfoy@cpan.org.

Shawn Sorichetti, <ssoriche@cpan.org>

SOURCE AVAILABILITY

This module is in Github:

http://github.com/briandfoy/test-output

BUGS

Please report any bugs or feature requests to bug-test-output@rt.cpan.org, or through the web interface at http://rt.cpan.org. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

ACKNOWLEDGEMENTS

Thanks to chromatic whose TieOut.pm was the basis for capturing output.

Also thanks to rjbs for his help cleaning the documentation, and pushing me to Sub::Exporter. (This feature has been removed since it uses none of Sub::Exporter's strengths).

Thanks to David Wheeler for providing code block support and tests.

Thanks to Michael G Schwern for the solution to combining STDOUT and STDERR.

COPYRIGHT & LICENSE

Copyright 2005-2021 Shawn Sorichetti, All Rights Reserved.

This module is licensed under the Artistic License 2.0.