【问题标题】:In Test::More, is it possible to test a subroutine that exit()'s at the end?在 Test::More 中,是否可以测试一个以 exit() 结尾的子程序?
【发布时间】:2017-12-24 23:38:43
【问题描述】:

我有一个带有一些实用功能的模块。

其中一个功能只是一个使用说明(用户@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($0);
    for (@_)
    {
        print {*STDERR} $_;
    }
    print {*STDERR} "Try $PROG --help for more information.\n";
    exit 1;
}

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

【问题讨论】:

  • 也许你可以在 eval 块中运行它?
  • @DavidKnipe - 不,eval 只捕获 die,而不是 exit。如果你想自己测试一下,perl -E 'eval { exit } ; say "caught"' 不会产生任何输出。
  • 感谢您的信任(我假设这个想法)。注释:代码将打印 @_ 元素,它们之间没有任何内容。我想这不是意图,所以也许print {*STDERR} "@_\n" if @_;。引号下的数组被插值,其中 $, variable 的值(默认为空格)被添加到元素之间。
  • 好点!再次感谢@zdim!

标签: perl unit-testing perl-module


【解决方案1】:

您可以使用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 块之后加载您的模块。

【讨论】:

    【解决方案2】:

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

    在 END 代码块内,$?包含程序的值 将传递给 exit()。你可以修改 $?改变退出值 程序。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      相关资源
      最近更新 更多