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)
这有效,但有一个代码味道.我也不喜欢它在第一次警告时爆炸.我宁愿测试套件完全运行,记录所有警告,但测试状态最终失败,因为代码运行时出现警告.
有没有更好的方法来实现这个最终结果?
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)