每个人都使用一个很棒的Perl模块
Test :: More进行单元测试.这是一个非常简单的脚本t/sample_1.t:
use Test::More tests => 1;
fail('This test fails');
Run Code Online (Sandbox Code Playgroud)
我想编写执行相同操作的脚本,但没有 Test :: More.
我已经阅读了几篇关于TAP(测试任何协议)的文档,以了解如何编写脚本.我读了:
不幸的是文档还不够.我不得不检查使用Test :: More的脚本输出,以找出我需要向STDERR输出诊断信息(文档中没有任何内容).
所以,我编写了一个脚本,它与使用Test :: More脚本的脚本完全相同.这是列表t/sample_2.t:
$| = 1;
print "1..1\n";
print "not ok 1 - This test fails\n";
print STDERR "# Failed test 'This test fails'\n";
print STDERR "# at t/sample_1.t line 3.\n";
print STDERR "# Looks like you failed 1 test of 1.\n";
exit 1;
Run Code Online (Sandbox Code Playgroud)
但是当使用prove这两个脚本输出不同的东西时.prove对于不同的测试,"#Failed test'此测试失败'" 行显示在不同的行上.这是截图:

我编写了一个测试脚本,使用Capture :: Tiny检查两个脚本的STDERR,STDOUT和退出代码是否相同.脚本显示两个脚本输出相同的内容.
我已经将所有测试文件和测试脚本存储在GitHub repo中.
我的问题.如何在没有Test :: More的情况下编写Perl单元测试,以获得与Test :: More相同的输出.
我终于知道是怎么回事了。
hobbs建议我使用 Test::Builder。我使用Test::Builder创建了测试脚本 ,该脚本与 Test::More 的脚本完全一样(这里是)。
然后我开始检查Test::Builder的源代码以找出这种行为的根源。这是 lib/TB2/Formatter/TAP/Base.pm 文件的部分:
# Emit old style comment failure diagnostics
sub _comment_diagnostics {
my($self, $result) = @_;
...
# Start on a new line if we're being output by Test::Harness.
# Makes it easier to read
$self->$out_method("\n") if ($out_method eq 'err') and $ENV{HARNESS_ACTIVE};
$self->$diag_method($msg);
return;
}
Run Code Online (Sandbox Code Playgroud)
所以,这就是答案。prove设置特殊的环境变量
HARNESS_ACTIVE和 Test::More 以及朋友在打印到 STDERR 的任何诊断信息之前添加额外的换行符“\n”。
最后,我创建了测试脚本,其输出与使用 Test::More 编写的脚本完全相同。脚本的源代码。
我真的不喜欢这个解决方案。我和其他人花了很多时间才弄清楚发生了什么事。我确信漂亮输出的任务应该在 TAP 解析器中解决,而不是在 TAP 生成器中解决。
=(