NAME
Test::And::Output - Capture output during other tests
SYNOPSIS
#! C:/Perl/bin/perl
use Modern::Perl;
use Test::Most;
use Test::Moose;
use Test::Exception;
use Smart::Comments '###';
use Carp;
use Test::And::Output v0.003;
my ( $test_inst, $wait, $expected_count );
$| = 1;
### hard questions
lives_ok{ $test_inst = Test::And::Output->new(); } "Test that a new test instance begins";
### Testing STDOUT ...
$test_inst->cant_match_output( 'STDOUT', qr/Hello\sW/, "Test that 'Hello World' or a close match was (NOT) captured" );
$test_inst->no_buffer( 'STDOUT', "Test that the buffer for 'STDOUT' has not been created yet" );
$test_inst->capture_output( 'STDOUT', "Test turning on the capture for STDOUT" );
$test_inst->has_buffer( 'STDOUT', "Test that the buffer for 'STDOUT' HAS been created" );
ok print( "Hello World\n" ), "Test capturing 'Hello World'";
### Printing a Smart_Comment to ensure that it is NOT captured since it prints to STDERR! ...
$test_inst->return_to_screen( 'STDOUT', "Test turning off the capture for STDOUT" );
$test_inst->has_buffer( 'STDOUT', "Test that the buffer for 'STDOUT' is still in existence" );
$test_inst->buffer_count( 1, 'STDOUT', "... check if the 'STDOUT' buffer has the expected number of lines" );
ok print( "Foo, Bar, Baz\n" ), "Test printing 'Foo, Bar, Baz'";
$test_inst->cant_match_output( 'STDOUT', 'Foo, Bar, Baz',
"Test that 'Foo, Bar, Baz' was (NOT) captured in the print buffer" );
$test_inst->buffer_count( 1, 'STDOUT', "... check if the 'STDOUT' buffer (still) has the expected number of lines" );
$test_inst->match_output( 'STDOUT', qr/Hello\sW/, "Test that 'Hello World' or a close match was captured" );
$test_inst->buffer_count( 0, 'STDOUT', "... check that the 'STDOUT' buffer has one fewer lines" );
$test_inst->close_buffer( 'STDOUT', "Test closing the 'STDOUT' buffer" );
$test_inst->no_buffer( 'STDOUT', "Test that the buffer for 'STDOUT' is NOT in existence" );
$test_inst->return_to_screen( 'STDOUT', "... and return 'STDOUT' to screen" );
### Testing STDERR ...
$test_inst->cant_match_output( 'STDERR', qr/Watch out\sW/,
"Test that 'Watch out World!' or a close match was (NOT) captured" );
$test_inst->capture_output( 'STDERR', "Test turning on the capture for STDERR" );
ok warn( "Watch out World!" ), "Test capturing 'Watch out World!'";
$test_inst->return_to_screen( 'STDERR', "Test turning off the capture for STDERR" );
$expected_count = 1;
$test_inst->buffer_count( $expected_count, 'STDERR', "... check if the 'STDERR' buffer has the expected number of lines" );
ok warn( "Foo, Bar, Baz" ), "Test warning 'Foo, Bar, Baz'";
$test_inst->cant_match_output( 'STDERR', 'Foo, Bar, Baz',
"Test that 'Foo, Bar, Baz' was (NOT) captured in the warning buffer" );
$test_inst->buffer_count( $expected_count, 'STDERR', "... check if the 'STDERR' buffer (still) has the expected number of lines" );
print "Hello World 1\n";
warn "War of the Worlds";
$test_inst->match_output( 'STDERR', qr/Watch out\sW/, "Test that 'Watch out World!' or a close match was captured" );
$expected_count--;
print "Hello World 2\n";
warn "Watch out World 2";
$test_inst->cant_match_output( 'STDERR', qr/Watch out World 2/,
"Test that 'Watch out World 2' was NOT captured (Bug fix test case)" );
$test_inst->buffer_count( $expected_count, 'STDERR', "... check that the 'STDERR' buffer has one fewer lines" );
$test_inst->clear_buffer( 'STDERR', "Test clearing the 'STDERR' buffer" );
### Testing croak and carp...
$test_inst->capture_output( 'STDERR', "Test turning on the capture for STDERR" );
ok carp( "Grumpity Grumpity Grumpity" ), "Test capturing 'Grumpity Grumpity Grumpity'";
$test_inst->return_to_screen( 'STDERR', "Test turning off the capture for STDERR" );
$expected_count = 1;
$test_inst->buffer_count( $expected_count, 'STDERR', "... check if the 'STDERR' buffer has the expected number of lines" );
ok carp( "Foo, Bar, Baz" ), "Test carping 'Foo, Bar, Baz'";
$test_inst->cant_match_output( 'STDERR', 'Foo, Bar, Baz',
"Test that 'Foo, Bar, Baz' was (NOT) captured in the warning buffer" );
$test_inst->buffer_count( $expected_count, 'STDERR', "... check if the 'STDERR' buffer (still) has the expected number of lines" );
$test_inst->match_output( 'STDERR', qr/Grumpity Grumpity /,
"Test that 'Grumpity Grumpity Grumpity' or a close match was captured" );
$expected_count--;
$test_inst->buffer_count( $expected_count, 'STDERR', "... check that the 'STDERR' buffer has one fewer lines" );
$test_inst->clear_buffer( 'STDERR', "Test clearing the 'STDERR' buffer" );
### Testing croak ...
$test_inst->cant_match_output( 'STDERR', "You can’t win, Darth. If you strike me down, I shall become more powerful than you can possibly imagine.",
"Test that Obi-wans last corporeal words were (NOT) captured" );
$test_inst->capture_output( 'STDERR', "Test turning on the capture for STDERR" );
dies_ok{ croak "You can’t win, Darth. If you strike me down, I shall become more powerful than you can possibly imagine."}
"Die with Obi-wan's last corporeal words";
ok warn( @$ ), "Capture the words for testing";
dies_ok{ live_or_die( 'die', 'This is a test death' ) } "Test dieing by subroutine";
ok warn( @$ ), "Capture the words for testing";
lives_ok{ live_or_die( 'live', 'Princess Padme Amidala, you now have the floor.' ) }
"Test carping by subroutine";
$test_inst->return_to_screen( 'STDERR', "Test turning off the capture for STDERR" );
$expected_count = 10;
$test_inst->buffer_count( $expected_count, 'STDERR', "... check if the 'STDERR' buffer has the expected number of lines" );
dies_ok{ croak "Foo, Bar, Baz" } "Test croaking 'Foo, Bar, Baz'";
ok warn( @$ ), "Send output to 'STDERR' for testing";
$test_inst->cant_match_output( 'STDERR', 'Foo, Bar, Baz',
"Test that 'Foo, Bar, Baz' was (NOT) captured in the warning buffer" );
$test_inst->buffer_count( $expected_count, 'STDERR', "... check if the 'STDERR' buffer (still) has the expected number of lines" );
$test_inst->match_output( 'STDERR', qr/You can’t win, Darth. If you strike me down, I shall become more powerful than you can possibly imagine./,
"Test that Obi-wans last corporeal words were captured" );
$expected_count--;
$test_inst->buffer_count( $expected_count, 'STDERR', "... check that the 'STDERR' buffer has one fewer lines" );
lives_ok{ $test_inst->set_match_retention( 1 ) } "... change line matching behaviour to keep the line in the buffer after it is matched";
$test_inst->match_output( 'STDERR', qr/This is a test death/,
"Test that the subroutine test error was captured" );
$test_inst->buffer_count( $expected_count, 'STDERR', "... check that the 'STDERR' buffer has the expected number of lines" );
### Testing the global variable buffer ...
$test_inst->no_buffer( 'GENERIC', "Test that the buffer for 'GENERIC' has not been created yet" );
lives_ok{ $Test::And::Output::test_buffer->{GENERIC} = [
"Aren't you a little short for a stormtrooper?",
"That's no moon, it's a space station.",
"This is some rescue. You came in here and you didn't have a plan for getting out?",
] } "Test loading buffer 'GENERIC' with some lines";
$test_inst->has_buffer( 'GENERIC', "Test that the buffer for 'GENERIC' exists now" );
$test_inst->buffer_count( 3, 'GENERIC', "... check that the 'GENERIC' buffer has 3 lines" );
lives_ok{ $test_inst->set_match_retention( 0 ) } "... change line matching behaviour to discard the line from the buffer after it is matched";
$test_inst->match_output( 'GENERIC', qr/it's a space station/,
"Test that a space station exists" );
$test_inst->buffer_count( 2, 'GENERIC', "... check that the 'GENERIC' buffer has one less line" );
$test_inst->close_buffer( 'GENERIC', "Close the 'GENERIC' buffer" );
$test_inst->no_buffer( 'GENERIC', "... and see if the 'GENERIC' buffer is gone" );
### testing done ...
done_testing();
sub live_or_die{
my ( $input, $text ) = @_;
if( $input eq 'live' ){
carp $text if $text;
return 1;
}else{
croak $text || '';
return 0;
}
}
###############################
# Synopsis Screen Output
# All tests should pass!
###############################
JEDI mind trick
These arn't the droids you're looking for.... He can go about his buisness.... Move along....
Seriously, there are other modules that are written by perl masters, with more traditional interfaces, that have more time testing on CPAN, and are likly perfect for your testing needs. I reference Test::Output for example.
DESCRIPTION
"JEDI mind trick"s don't appear to work on you. Or you ran into one of the problems that I did and hope this is a solution.
You want to test the result of a function and still test the associated print (warning?) output
You were hoping to get a test case per output line instead of a single 'is_deeply' compare
You are addicted to Smart::Comments and test driven development so you don't want the Smart Comments captured while running the tests for STDOUT captures. (Smart::Comments are sent to STDERR) This way you can write code and get Smart::Comments prior to fully complete functionality while still testing for correct STDOUT output when running early tests.
You're strangly attracted to an OO testing interface (why????)
You are looking for a Moose Testing class that you can leverage to test content in a global variable without writing the thing from scratch.
At this point if something didn't ring true I would encourage you to review Test::Output and Test::Exception or as a minimum check out the perl man page dealing with open and review the section "To (re)open STDOUT or STDERR as an in-memory file".
This is indeed a Moose based OO testing Class. It is dependency heavy. Your test calls will require '->'. The module is NOT mature. These arn't the droids your looking for...
Please note that when used in conjuntion with dies_ok from Test::Exception you have to run another command 'warn( @$ );' in order to get the dies_ok warnings or carps into the buffer for testing.
Attributes
Data passed to ->new when creating an instance using a class. For modification of this attribute see "Methods".
keep_matches( $bool )
- Definition: this determines whether a line is deleted from the capture buffer after it is matched using a match test. The line will never be deleted in a "cant_match_output" test!
- Default False (0) = 'delete matches'
- Range This is a Boolean data type and generally accepts 1 or 0
Non Test Methods
These are class methods that do something but do NOT produce TAP output.
set_match_retention( $bool )
- Definition: This is the way to change the "keep_matches" attribute
- Accepts: a Boolean value (1/0)
- Returns: ''
get_buffer( $buffer )
- Definition: This method will return any items in the buffer list. If there is no buffer it will return an empty list. If the buffer exists but is empty it will return an empty list. (You can't use this to test for list existence.) See "has_buffer"
- Accepts: a $string that can be used as a buffer name (must comply with all hash key naming restrictions. Can include STDERR and STDOUT.
- Returns: An array (not a ref) of the buffer lines. For STDOUT and STDERR the array is split on newlines so if the output contained newlines there will be one item per line.
Test Methods
These are tests that will produce standard TAP output. They are built with Test::Builder.
capture_output( $buffer, $test_description )
- Definition: This method will begin to redirect STDERR or STDOUT output to a buffer. (and therefore no-longer print to screen) If you call out another name then it creates a top level buffer key in the global variable $Test::And::Output::test_buffer. This method always clears the buffer!
- Accepts:
- Returns: TAP output - passing means there is (now) a cleared buffer for that name
has_buffer( $buffer, $test_description )
- Definition: This method tests for the existence of a buffer.
- Accepts:
- Returns: TAP output - passes if the buffer exists
no_buffer( $buffer, $test_description )
clear_buffer( $buffer, $test_description )
- Definition: This method clears the contents of the named buffer but does not delete it. If the buffer does not exist the test fails.
- Accepts:
- Returns: TAP output that passes if the buffer exists and is cleared.
return_to_screen( $buffer, $test_description )
- Definition: This method takes STDERR or STDOUT and changes the output back to the screen.
- Accepts:
- Returns: TAP output - passes if 'STDERR' or 'STDOUT' are sent back to the screen.
close_buffer( $buffer, $test_description )
- Definition: This method closes the buffer. Future tests for that buffer will show that it doesn't exist. If the buffer is STDERR or STDOUT the output will be redirected to the screen prior to closure.
- Accepts:
- Returns: TAP output - passes if the buffer is succesfully closed.
buffer_count( $expected_count, $buffer, $test_description )
- Definition: This method checks to see if the expected number of items are in the buffer indicated. This is not an existence test. Non existent buffers will return a quantity of 0!
- Accepts:
- Returns: TAP output - passes if the buffer has the expected number of items.
match_output( $buffer, $line, $description )
- Definition: This test will search the $buffer for a $line. If a string is passed an exact match is required. if a regex (qr/something/) is passed then each item of the @$buffer will be bound to the regex attempting a match. The test will pass if a match is found. See the "keep_matches" attribute for the disposition of the matched line in the buffer. For STDOUT and STDERR the buffers are stored as strings and then returned as lists split on \n so multiline matches require multiple tests. For global buffers the data goes in any way you load it with the assumption that it is stored as an ArrayRef.
- Accepts:
- Returns: TAP output - pass indicates that a match was found
cant_match_output( $buffer, $line, $description )
- Definition: This test will search the $buffer for $line. If a string is passed an exact match is required. if a regex (qr/something/) is passed then each item of the @$buffer will be bound to the regex attempting a match. The test will fail if a match is found. Even if a match is found the matching line is not removed from the buffer. For STDOUT and STDERR the buffers are stored as strings and then returned as lists split on \n so multiline matches require multiple tests. For global buffers the data goes in any way you load it with the assumption that it is stored as an ArrayRef.
- Accepts:
- Returns: the TAP output where pass indicates that NO match was found
SUPPORT
AUTHOR
COPYRIGHT
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the LICENSE file included with this module.
DEPENDENCIES
- 5.008 - uses the print to in-memory string capability
- Smart::Comments
-
with the '-ENV' option set
- Moose
- MooseX::NonMoose
- YAML::Any
-
Only used if $ENV{Smart_Comments} = '#####' is called. (Dumps some nice file handle info)
- Test::Builder
- Test::Builder::Module
- MooseX::StrictConstructor
- version
- Carp
- MooseX::Types::Moose
SEE ALSO
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 661:
Non-ASCII character seen before =encoding in 'can’t'. Assuming CP1252