tom*_*dee 34 testing perl unit-testing
我正在尝试使用Test :: More来测试打印到屏幕的Perl函数.
我知道这个输出可能会干扰诸如证明之类的工具.
如何捕获此输出以便我可以打印它diag(),并在输出本身上运行测试?
Sin*_*nür 32
更新:恕我直言,这个问题的正确答案应该是使用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');
Run Code Online (Sandbox Code Playgroud)
输出:
C:\Temp> tm 1..1 ok 1 - myfunc() returns test output
我将离开原始答案以供参考,我相信,它仍然说明了一种有用的技术.
STDOUT在调用函数之前,您可以本地化并重新打开标量,然后恢复:
#!/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'");
Run Code Online (Sandbox Code Playgroud)
输出:
C:\Temp> tm 1..1 ok 1 - myfunc() prints test string # myfunc() printed 'This is a test'
对于perl早于5.8的版本,您可能需要使用IO :: Scalar,但我不太了解5.8之前的工作原理.
如果这是您自己编写的代码,请更改它以使print语句不使用默认文件句柄.相反,给自己一个方法将输出文件句柄设置为你喜欢的任何东西:
sub my_print {
my $self = shift;
my $fh = $self->_get_output_fh;
print { $fh } @_;
}
sub _get_output_fh { $_[0]->{_output} || \*STDOUT }
sub _set_output_fh { $_[0]->{_output} = $_[1] } # add validation yourself
当你测试时,你可以调用_set_output_fh它给你的测试文件句柄(甚至可能是一个IO :: Null句柄).当另一个人想要使用你的代码但是捕获输出时,他们不必向后弯腰来执行它,因为他们可以提供他们自己的文件句柄.
当您发现代码的一部分难以测试或者您必须跳过箍来使用时,您的设计可能很糟糕.我仍然对测试代码如何使这些事情变得明显感到惊讶,因为我经常不会考虑它们.如果难以测试,请轻松测试.如果你这样做,你通常会赢.
| 归档时间: |
|
| 查看次数: |
4055 次 |
| 最近记录: |