Test::Output(3)

πŸ’… Test::Output

okay bestie, so this whole thing lives in the User Contributed Perl Documentation section of your man pages, and it's literally called Test::Output β€” that's the name of the module and the name of the page. iconic. πŸŽ€


✨ NAME ✨

Test::Output β€” utilities to test STDOUT and STDERR messages. that's it. that's the whole vibe. πŸ¦‹


🌸 SYNOPSIS 🌸

so here's how you run it, no cap:

    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'
            );

and you can also use bare blocks, which is honestly giving main character energy:

   # 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 gives you a genuinely simple interface for testing output that gets beamed out to "STDOUT" or "STDERR". there are a bunch of different utilities bundled in so it can be as flexible as possible for whoever's writing the tests. lowkey thoughtful of it. 🫢

and just so you know: Capture::Tiny provides a much more robust capture mechanism than the original Test::Output::Tie. (yes, we know, we know. 🩷)


🧚 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 the output sent to "STDOUT" from $coderef and compares it against $expected. the test passes if they're 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 basically stdout_is's sibling, except it captures "STDERR". the test passes if the "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 just like stdout_like(), except it compares the regex $expected to the "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" into "STDOUT" and then captures "STDOUT". that's equivalent to UNIX's "2>&1". the test passes if the combined "STDOUT" and "STDERR" from $coderef equals $expected. πŸ‘‘

combined_isnt() passes if the 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 it compares a regex ("$expected)") to the "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 combo of stdout_is() and stderr_is(). like, watch:

  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 β€” and this is the important bit β€” $coderef is only executed once. periodt. πŸ’…

unlike stdout_is() and stderr_is(), which ignore STDERR and STDOUT respectively, output_is() needs both "STDOUT" and "STDERR" to match in order to pass. so if you set either $expected_stdout or $expected_stderr to "undef", that 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() is the opposite function of output_is(). it's 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');

and just like 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. cute. πŸ¦‹

output_like() tries to match $regex_stdout and $regex_stderr against the "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 test above is successful. slay. ✨

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()'s test passes if the output from $coderef doesn't match $regex_stdout and $regex_stderr. πŸ™ˆ


🎁 EXPORTS 🎁

by default, all subroutines are exported by default. (yes, that's what it says, and honestly? mood.) πŸ’…

  • :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 while capturing both "STDOUT" and "STDERR". efficient queen. ⭐

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. team work makes the dream work fr fr. πŸ™


🌟 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 2005-2021 Shawn Sorichetti, All Rights Reserved.

this module is licensed under the Artistic License 2.0.


and that's the whole page bestie πŸ’– β€” brought to you by perl v5.42.0, dated 2023-07-06, going out as Test::Output(3). go forth and test your output, you absolute icon. πŸŽ€βœ¨

πŸ“¦ where this page comes from