如何在Perl中测试异常

大多数Perl程序员都熟悉Test::More;它是Perl中编写单元测试的首选库。但是Test::More不提供测试异常的函数。为此你需要Test::Exception。好的代码会抛出异常 - Paul Fenwick 曾经很好地总结了这种方法
bIlujDI' yIchegh()Qo'; yIHegh()!
It is better to die() than to return() in failure.
-- Klingon programming proverb.
抛出异常最简单的方法是使用Perl的内置die
函数。就像Test::More使得测试子程序返回正确的值变得容易一样,Test::Exception使得检查代码是否以正确的方式死亡变得容易(Test::Fatal是一个不错的选择)。
我的代码是否死亡了?
假设我们正在为以下包编写单元测试,该包导出double_integer
子程序
package Double;
use Exporter;
@ISA = 'Exporter';
@EXPORT = 'double_integer';
sub double_integer
{
my ($number) = @_;
die 'double_integer() requires a positive integer as an argument'
unless defined $number && $number =~ /^\d+$/;
return $number * 2;
}
1;
除非以正整数调用double_integer子程序,否则此代码将die
。我将此包保存为Double.pm
。让我们为这个包编写一个测试脚本。Test::Exception导出dies_ok
函数,该函数检查代码是否按预期死亡
use Test::Exception tests => 1;
use Double;
dies_ok { double_integer() } 'double_integer() dies with no number';
dies_ok
很聪明,它实际上不会让您的代码死亡并退出程序,因为这会中断测试!相反,它会捕获任何抛出的异常,以便测试可以继续。我的程序也应该在以非数字作为参数调用double_integer
时死亡。我可以为一些常见场景添加更多测试
use Test::Exception test => 6;
use Double;
dies_ok { double_integer() } 'double_integer() dies with no number';
dies_ok { double_integer(undef) } 'double_integer() dies with undef';
dies_ok { double_integer('abc') } 'double_integer() dies with text';
dies_ok { double_integer('1 two') } 'double_integer() dies with mixed';
dies_ok { double_integer('-7') } 'double_integer() dies with a negative';
dies_ok { double_integer('2.5') } 'double_integer() dies with a decimal';
我还可以使用throws_ok
检查代码抛出了正确的异常
use Test::Exception tests => 1;
use Double;
throws_ok { double_integer() } qr/requires a positive integer/,
'double_integer() requires a positive integer';
throws_ok
函数检查代码抛出了异常,而且还匹配正则表达式异常消息。如果您有几个可能抛出不同类型异常的不同条件,这很有用:想象一下在一个Web应用程序中,如果您想要在用户请求他们没有权限访问的页面(403)和请求一个不存在的页面(404)时抛出不同的异常代码。
Test::Exception与Test::More完全兼容,因此您可以在同一文件中组合两个库的函数
use Test::More;
use Test::Exception;
use Double;
# test arg validation works
dies_ok { double_integer() } 'double_integer() dies with no number';
dies_ok { double_integer(undef) } 'double_integer() dies with undef';
dies_ok { double_integer('abc') } 'double_integer() dies with text';
dies_ok { double_integer('1 two') } 'double_integer() dies with mixed';
dies_ok { double_integer('-7') } 'double_integer() dies with a negative';
dies_ok { double_integer('2.5') } 'double_integer() dies with a decimal';
# test exception message
throws_ok { double_integer() } qr/requires a positive integer/,
'double_integer() requires a positive integer';
# test double_integer works
lives_ok { double_integer(1) } 'calling double() with a number lives';
is double_integer(0), 0, 'zero doubled is zero';
is double_integer(2), 4, 'two doubled is four';
is double_integer(999), 1998,
'nine nine nine doubled is one nine nine eight';
done_testing();
现在测试脚本检查了当参数不正确时函数是否抛出了适当的异常,并且当参数正确时返回参数的两倍。如果我把这个测试文件保存为Double.t
,我就可以在终端运行测试
$ perl Double.t
ok 1 - double_integer() dies with no number
ok 2 - double_integer() dies with undef
ok 3 - double_integer() dies with text
ok 4 - double_integer() dies with mixed
ok 5 - double_integer() dies with a negative
ok 6 - double_integer() dies with a decimal
ok 7 - double_integer() requires a positive integer
ok 8 - calling double() with a number lives
ok 9 - zero doubled is zero
ok 10 - two doubled is four
ok 11 - nine nine nine doubled is one nine nine eight
1..11
所有测试都通过了。Test::Exception具有出色的文档,易于使用,所以请今天就把异常测试添加到您的代码中!
更新: 添加了Test::Fatal参考 2015-03-10
这篇文章最初发布在PerlTricks.com。
标签
反馈
这篇文章有什么问题吗?请通过在GitHub上打开问题或拉取请求来帮助我们。