4

我运行了这个测试脚本:

use strict;
use warnings;
use Test::More tests => 3;
use Carp;

ok(1<2);
pass();
fail();
croak "example";

使用命令行prove -MCarp=verbose -v foo.pl,并得到以下错误:

Subroutine App::Prove::verbose redefined at /opt/ActivePerl-5.12/lib/App/Prove.pm line 407
        App::Prove::_load_extension('App::Prove=HASH(0x683718)', 'Carp=verbose') called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 419
        App::Prove::_load_extensions('App::Prove=HASH(0x683718)', 'ARRAY(0x683850)') called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 481
        App::Prove::run('App::Prove=HASH(0x683718)') called at /opt/ActivePerl-5.12/bin/prove line 11
Undefined subroutine &Carp::verbose called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 484.

如果我使用它运行它perl -MCarp=verbose foo.pl没有问题。是什么导致prove拒绝冗长的鲤鱼?croak当我的测试没有全局替换croakto时,如何从我的测试中获得完整的调用堆栈confess

4

3 回答 3

10

prove -M似乎不等同于perl -M。它似乎加载了一个证明扩展,而不是将模块加载到您的测试中。文档在这一点上完全不清楚,但 App::Prove 中的代码不是。因此prove -MCarp=verbose将 Carp::verbose 导入 App::Prove 会导致上述问题。

做你想做的事的一个简单方法是使用 PERL5OPT 环境变量加上Carp::Always它将所有警告和死亡(以及鲤鱼和呱呱叫)变成堆栈跟踪。

PERL5OPT=-MCarp::Always prove ...

这具有在任何情况下工作的额外好处,无论是否经过证明。

于 2010-08-31T01:38:58.993 回答
3

证明与 perl 有一组非常不同的命令行参数,是一个完全不同的程序?

我相信证明的 -M 旨在启用编译指示;Carp 实际上导出了对 verbose() 子例程的前向引用,这会干扰prove 的内部工作。

您可以像这样创建一个小模块:

# Verbme.pm
use Carp;
$Carp::Verbose = 1;

并通过证明启用它:

prove -MVerbme -v foo.pl

尽管。

于 2010-08-31T01:37:52.950 回答
2

Carp 使用 Exporter 的EXPORT_FAIL机制来处理 to 的verbose“选项” import,这是非常错误的,尽管它“失败”了,但Exporter::Heavy仍会尝试分配*Carp::verboseto 。*{"$callerpkg::verbose"}不幸的是,App::Prove它有一个详细的 sub 依赖于它的工作,并且您的 -M 选项会导致导入在App::Prove. 我不确定这里应该责备谁——Carp因为(ab)EXPORT_FAIL以这种方式使用,或者如果它在列表中,Exporter::Heavy则不删除它,但他们一起破坏了它:)@imports@failed

于 2010-08-31T01:43:37.343 回答