用于测试 Perl script/module 异常和死亡的单元测试

Unit test for testing Perl script/module exceptions and dieing

我正在尝试使用 Test::MoreTest::Exception 库为我的脚本创建单元测试。
我已经阅读了这些文章 How to test for exceptions in Perl and Test::Exception
第一篇文章准确描述了我需要什么,以测试我的子例程是否抛出异常或死亡。
但我无法让它工作。考虑一些例子

    #!/usr/bin/env perl
    package My::SuperModule;
    use strict;
    use warnings;
    use Net::Ping;
    use Utils::Variables::Validator;

    sub new
    {
        die "Hello";
        #Getting class name from, stored in $_[0]
        my $class = shift;
        #Getting user name from arguments $_[1]
        my $user_name = shift;
    ........
}

还有我的测试文件

    use warnings;    # this warns you of bad practices
    use strict;      # this prevents silly errors
    use Test::More; # for the is() and isnt() functions
    use Test::Exception;
    do './My/SuperModule.pm';
    #Testing module loading 
    print "=================Testing module loading=================\n";
    use_ok ( 'My::SuperModule' );
    use_ok ( 'My::SuperModule', 'new' );
    #Testing module subroutines
    dies_ok { My::SuperModule->new() } "Died in class constructor";
     sub div {
    my ( $a, $b ) = @_;
    return $a / $b;
};
    dies_ok { div( 1, 0 ) } 'divide by zero detected';

它在任何情况下都停止执行脚本,但我只需要处理是否死了,我需要测试这个,因为如果数据无效或其他原因我手动调用死,但它死了并且不会继续执行脚本进一步。给我留言

Uncaught exception from user code:
    Hello at ../libs/My/SuperModule.pm line 31.
    My::SuperModule::new('My::SuperModule', '') called at SuperModule.t line 24
# Tests were run but no plan was declared and done_testing() was not seen.
# Looks like your test exited with 2 just after 8.

但是如果使用除以零它会像我想要的那样工作

ok 16 - divide by zero detected

所以它失败了,但不会终止脚本的执行。

我是Perl的新手,所以不能自己解决问题,也许根本就没有问题,只是没有办法做我想做的事。
请在这里建议做什么或说我的错在哪里。

编辑

我刚刚尝试在我的模块新子例程中除以零,这是我收到的消息。

Illegal division by zero at ../libs/My/SuperModule.pm line 33 (#1)
    (F) You tried to divide a number by 0.  Either something was wrong in
    your logic, or you need to put a conditional in to guard against
    meaningless input.

我实在想不通这是怎么回事。请帮忙解决这个问题。

对我有用。我需要做的就是:

  1. 注释掉测试未使用的两个模块(Net::Ping 和 Utils::Variables::Validator - 我没有安装它们)。
  2. 添加 1; 作为模块的最后一行 - 所以它 returns 是一个真实的值。
  3. 从测试中删除多余的 requireuse_ok
  4. 在测试结束时添加了 done_testing; - 因此测试工具知道它已到达测试结束。

您可能不关心该列表中的第一项,但如果您修复了其他项,它应该对您有用。

这是一个有效的最小示例:

package My::SuperModule;
use strict;
use warnings;

sub new {
    die "Hello";
}

package main;

run() unless caller;

use Test::More;
use Test::Exception;

sub run {
    dies_ok { My::SuperModule->new } "dies ok";
    done_testing;
}

输出:

C:\...\t> prove -v my.pl
my.pl ..
ok 1 - dies ok
1..1
ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.09 usr +  0.00 sys =  0.09 CPU)
Result: PASS

请注意,为了提供一个独立的示例,我将模块代码和测试脚本合并到一个文件中。

另请注意,我没有用不必要的 print 语句使测试脚本混乱。

如果需要,可以使用 diag 显示一些输出:

diag "Checking if Test::Exception::dies_ok will catch die in new";
dies_ok { My::SuperModule->new } "dies ok";
done_testing;

输出:

C:\...\t> prove my.pl
my.pl .. # Checking if Test::Exception::dies_ok will catch die in new
my.pl .. ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.05 usr +  0.02 sys =  0.06 CPU)
Result: PASS

与普通的 print 语句相反,diag 输出实际上会在测试 运行 来自 prove.

等线束时实际显示