在 Test::More 中,是否可以测试最后 exit() 的子程序?

In Test::More, is it possible to test a subroutine that exit()'s at the end?

我有一个用一些实用函数编写的模块。

其中一个功能只是一个用法说明(用户@zdim推荐)

use 5.008_008;
use strict;
use warnings;

# Function Name:        'usage'
# Function Inputs:      'none'
# Function Returns:     'none'
# Function Description: 'Prints usage on STDERR, for when invalid options are passed'
sub usage ## no critic qw(RequireArgUnpacking)
{
    require File::Basename;
    my $PROG = File::Basename::basename([=11=]);
    for (@_)
    {
        print {*STDERR} $_;
    }
    print {*STDERR} "Try $PROG --help for more information.\n";
    exit 1;
}

我知道该子例程按预期工作,而且它很简单,可以测试,但是...对于覆盖率报告,我想将它包含在我的单元测试中。 有什么方法可以使用 Test::More?

进行测试吗?

您可以使用 Test::Exit.

如果由于任何原因您无法使用它,只需复制以下代码:

our $exit_handler = sub {
    CORE::exit $_[0];
};

BEGIN {
    *CORE::GLOBAL::exit = sub (;$) {
        $exit_handler->(@_ ? 0 + $_[0] : 0)
    };
}

{
    my $exit = 0;
    local $exit_handler = sub {
        $exit = $_[0];
        no warnings qw( exiting );
        last TEST;
    };

    TEST: {
       # Your test here
    }

    cmp_ok($exit, '==', 1, "exited with 1");
}

确保在 BEGIN 块之后加载模块。

或者,您可以使用 END 块来处理退出调用。

Inside an END code block, $? contains the value that the program is going to pass to exit(). You can modify $? to change the exit value of the program.

usage();

END {
    use Test::More;
    ok($?);
    done_testing();
}

演示:https://ideone.com/AQx395