在按顺序加载模块时,如何使用Test :: NoWarnings捕获EXPORT()ed子例程的重定义错误

时间:2012-05-03 23:53:21

标签: perl unit-testing warnings

我正在使用基于Test::More的单元测试来部署我们的代码库,该代码库按use_ok()的顺序加载所有内部模块。我想对单元测试发出致命警告,以便我们更容易发现回归。

有人建议here使用Test::NoWarnings,这确实是我正在寻找的。

脚本在这里:

#!/usr/bin/perl -w
use File::Find;
use File::Spec;
use Test::More;
use Test::NoWarnings;


# Determine the filepaths of every .pm file in the lib directory
my @files;
File::Find::find(
    sub
    {
        if (/\.pm$/)
        {
            push(@files, $File::Find::name);
        }
    },
    "$ENV{'CODE_ROOT'}/lib"
);
done_testing(scalar(@files) + 1);

use lib "$ENV{'CODE_ROOT'}/lib";
foreach my $file (@files)
{
    # <code removed for brevity: format file name into Module::Hierarchy::For::Use>
    use_ok($includeString);
}

1;

我遇到过一些案例,其中不同模块编写的子例程EXPORT()引发了重新定义警告,但Test::NoWarnings模块没有捕获这些警告。相反,正确捕获由于小写属性声明引起的警告。

要明确,我阅读有关使用EXPORT() vs EXPORT_OK()的警告,并且正在处理警告本身的来源。我特别想知道我对Test::NoWarnings行为的假设是否正确,如果是,我如何改变单元测试以便捕获这些东西。

1 个答案:

答案 0 :(得分:1)

如果你想让警告致命,那么只是打开它?

use strict;
use warnings FATAL => 'all';

是的,warnings pragma的POD强烈反对使用此选项:

  

应谨慎使用致命警告,特别是FATAL => 'all'

  

使用FATAL =&gt; &#39;所有&#39;不鼓励

但我认为在回归或单元测试中使用是一个有效的用例。我已经在我的所有单元和回归测试中使用了这个很长一段时间,但没有出现意想不到的后果(尚未)。我认为Test::WarnTest::NoWarnings最适合用于捕捉您的模块&#39;自己的警告,无论是预期的还是意外的。

use strict;
use warnings FATAL => 'all';
use Test::More;
use Test::Warn;             # test for our own expected warnings                
require Test::NoWarnings;   # REQUIRE to suppress auto test at program exit     

my $tCnt = 0;
ok(1, "first test");                                               $tCnt++;
warning_like { warn("my warn") } (qr/my warn/), "caught warning";  $tCnt++;
ok(1, "made it to the end");                                       $tCnt++;
Test::NoWarnings::had_no_warnings();                               $tCnt++;

done_testing($tCnt);

如果你抛出像length("123");这样的语句(void context),编译时警告会启动你,FATALS => 'all'生效。没有它,所有测试都会运行并通过,而不会出现潜在问题。