如何在开发期间将Perl警告提升为致命错误?

His*_*air 13 perl continuous-integration warnings unit-testing

在运行应用程序测试套件时,我想将所有Perl编译和运行时警告(例如"未初始化的变量"警告)提升为致命错误,以便我和其他开发人员调查并修复生成警告的代码.但我只想在开发和CI测试期间这样做.在生产中,警告应该保持警告状态.

我尝试了以下内容:在"t/lib"中我创建了一个模块TestHelper.pm:

# TestHelper.pm
use warnings FATAL => qw( all );
1;
Run Code Online (Sandbox Code Playgroud)

然后像这样调用测试套件:

$ PERL5LIB=$PERL5LIB:./t/lib PERL5OPT=-MTestHelper.pm prove -l t/*.t
Run Code Online (Sandbox Code Playgroud)

但是,这并没有达到预期所有致命错误警告的效果.我得到了正常的警告,但警告似乎没有被视为致命的.请注意,我的所有test.t脚本都有"使用警告"行; 在它们中 - 也许这超过了TestHelper.pm中的一个,因为"使用警告"具有本地范围?

相反,我做到了这一点:

# TestHelper.pm
# Promote all warnings to fatal 
$SIG{__WARN__} = sub { die @_; };
1;
Run Code Online (Sandbox Code Playgroud)

这有效,但有一个代码味道.我也不喜欢它在第一次警告时爆炸.我宁愿测试套件完全运行,记录所有警告,但测试状态最终失败,因为代码运行时出现警告.

有没有更好的方法来实现这个最终结果?

cjm*_*cjm 21

我想你正在寻找Test :: NoWarnings.


fri*_*edo 17

原因use warnings FATAL => qw( all );不适合你是因为use warnings词汇范围.因此,TestHelper.pm中产生的任何警告都是致命的,但其他地方产生的警告将正常工作.

如果你想在全局启用致命警告,我认为$SIG{__WARN__}处理程序可能是唯一的方法.如果你不希望它爆炸第一个警告,你可以让你的处理程序将它们存储在一个数组中,然后在一个END块中检查它.

my @WARNINGS;
$SIG{__WARN__} = sub { push @WARNINGS, shift };

END { 
    if ( @WARNINGS )  {       
        print STDERR "There were warnings!\n";
        print "$_\n" for @WARNINGS;
        exit 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 词汇范围与包裹无关.它从声明点到文件末尾(或结束大括号,如果它在花括号内)运行.它从不影响另一个文件中的代码. (4认同)