Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I unit test Perl functions that print to the screen?

I'm trying to use Test::More to unit test Perl functions that print to the screen.

I understand that this output may interfere with tools such as prove.

How can I capture this output so I can print it with diag(), and also run tests on the output itself?

like image 869
tomdee Avatar asked Oct 08 '09 14:10

tomdee


People also ask

How do I write a test case in Perl?

Write Test Cases with Test::Simple #!/usr/bin/perl use strict; use warnings; use Test::Simple tests => 2; sub hello_world { return "Hello world!"; } sub get_number { return int(rand(1000)); } ok( hello_world( ) eq "Hello world!", "My Testcase 1" ); ok( get_number( ) > 0, "My Testcase 2" );

What is unit test script?

Unit testing is one of the steps in the software development process where every part or unit of code is verified to ensure it behaves as expected. When the code is modified in the future, the automated unit tests help ensure the existing functionality is intact. Unit tests can be done manually or coded.


1 Answers

UPDATE: IMHO, the correct answer to this question ought to be to use Test::Output:

#!/usr/bin/perl  use strict; use warnings;  use Test::More tests => 1; use Test::Output;  sub myfunc { print "This is a test\n" }  stdout_is(\&myfunc, "This is a test\n", 'myfunc() returns test output'); 

Output:

 C:\Temp> tm 1..1 ok 1 - myfunc() returns test output 

I am leaving the original answer for reference as, I believe, it still illustrates a useful technique.

You can localize STDOUT and reopen to a scalar before calling the function, restore afterward:

#!/usr/bin/perl  use strict; use warnings;  use Test::More tests => 1;  sub myfunc { print "This is a test\n" }  sub invoke {     my $sub = shift;     my $stdout;     {         local *STDOUT;         open STDOUT, '>', \$stdout             or die "Cannot open STDOUT to a scalar: $!";         $sub->(@_);         close STDOUT             or die "Cannot close redirected STDOUT: $!";     }     return $stdout; }  chomp(my $ret =  invoke(\&myfunc));  ok($ret eq "This is a test", "myfunc() prints test string" ); diag("myfunc() printed '$ret'"); 

Output:

 C:\Temp> tm 1..1 ok 1 - myfunc() prints test string # myfunc() printed 'This is a test' 

For versions of perl older than 5.8, you probably need to use IO::Scalar, but I do not know much about how things worked before 5.8.

like image 185
10 revs Avatar answered Oct 14 '22 08:10

10 revs