首页 文章

如何使用Try :: Tiny“捕获”Perl脚本中的pod2usage出口?

提问于
浏览
1

我目前正在尝试学习单元测试 . 为此,我正在编写脚本,我正在为整个脚本创建单元测试 . 到目前为止,事情进展顺利,但我正在尝试测试从命令行触发帮助消息的脚本中输入的错误数据 .

我的代码看起来像:

sub getContext{
   my ($help) = @_;

GetOptions(
  help|h => \$help,
   ...

pod2usage if $help;
... 
}

我的测试看起来像:

my $help_exception = 0;
try{  
   getContext( {help => 0} );
}catch{
 $help_exception = 1; 
}

ok($help_exception, "Script died correctly when given help flag");

我的输出看起来非常类似于:

1..4

ok 1 - use scripts::scriptname;

ok 2

ok 3

# Looks like you planned 4 tests but ran 3.

# Looks like your test exited with 1 just after 3.

帮助标志的测试是测试4,看起来我的脚本正在退出而没有触发Try :: Tiny try catch块 . 有没有办法解决这个问题,还是我应该以不同的方式编写测试?

3 回答

  • 1

    Pod::Usage 's documentation for it' s -exitval 参数显示了如何阻止它一起退出 . 您可以简单地使用它并相应地调整您的代码和/或测试 .

    否则, exit 不是例外,因此不像异常那样可以捕获 . 但是,它可以通过 CORE::GLOBAL::exit 覆盖 . 使用它也是一种合理的方法,假设您正确地对您的修改进行了本地化 .

    或者,你总是可以启动一个子进程来运行你的整个脚本并捕获它的作用,基于你的测试,完全避免 Pod::Usage 调用 exit 的问题 .

    在相关的说明中,您在测试中使用 Try::Tiny 的方式有点奇怪 . 我相信使用Test::Fatal(基于 Try::Tiny )可能会在未来进行更清晰的测试 .

  • 2

    问题是 pod2usage 确实 exit 并没有抛出异常 . 我认为不能以这种方式捕获它 .

    为什么不在测试中调用整个脚本并检查返回值/输出是否符合您的期望?

  • 4

    正如bvr回答的那样:程序/脚本实际上不是单元可测试的,因为它不是由可重用的部件/单元组成 . 你应该从整体上进行测试 . 使用命令行参数执行它并检查其输出和错误 . 例如,使用Capture::Tiny -

    use warnings;
    use strict;
    use Capture::Tiny qw( capture );
    use Test::More;
    
    my $script = "/bin/ls";
    
    plan skip_all => "Have no `$script` to check"
        unless -x $script;
    
    my ( $out, $err ) = capture {
        system($script, "-1", "/");
    };
    
    like( $out, qr{^bin$}m, "$script finds bin" );
    ok( ! $err, "...without error" );
    
    done_testing(2);
    

    输出 prove -

    /home/apv/ab ..
    ok 1 - /bin/ls finds bin
    ok 2 - ...without error
    1..2
    ok
    All tests successful.
    

相关问题