我对 Perl 还比较陌生,想知道是否有首选的单元测试框架?
谷歌给我展示了一些不错的结果,但由于我还是新手,不知道社区内是否有明确的偏好。
我对 Perl 还比较陌生,想知道是否有首选的单元测试框架?
谷歌给我展示了一些不错的结果,但由于我还是新手,不知道社区内是否有明确的偏好。
use 5.012;
use warnings;
use Test::More tests => 3;
my $foo = 5;
my $bar = 6;
ok $foo == 5, 'Foo was assigned 5.';
ok $bar == 6, 'Bar was assigned 6.';
ok $foo + $bar == 11, 'Addition works correctly.';
输出将是:
ok 1 - Foo was assigned 5.
ok 2 - Bar was assigned 6.
ok 3 - Addition works correctly.
此外,正如Schwern所指出的那样,几乎所有现代的Test::
模块都可以一起使用。这意味着您可以使用Test::Class
(由Markus指出)与rjh的answer中列出的所有优秀模块一起使用。实际上,因为Test::Builder——Test::More
和其他模块构建在其之上(并且目前由Schwern维护...感谢Schwern!)——如果需要,您可以从头开始构建自己的测试子例程,并且它们将与所有其他测试框架一起工作。仅这一点就使得Perl的TAP系统在我看来是最好的:所有东西都可以一起工作,每个人都使用相同的工具,您可以添加到框架以满足您的需求,而只需要很少的额外工作。
Perl最受欢迎的测试“框架”是一种称为TAP(Test Anything Protocol)的测试结果格式,它是一组看起来像这样的字符串:
ok 1 - Imported correctly
ok 2 - foo() takes two arguments
not ok 3 - foo() throws an error if passed no arguments
.t
结尾,例如 foo.t
)use strict;
use warnings;
use Test::More tests => 3; # Tell Test::More you intend to do 3 tests
my $foo = 3;
ok(defined $foo, 'foo is defined');
is($foo, 3, 'foo is 3');
$foo++;
is($foo, 4, 'incremented foo');
prove
调用)按顺序运行一系列测试,并获取哪些测试通过或失败的摘要。Test::Exception - 测试你的代码是否会抛出错误/不会抛出任何错误
Test::Warn - 测试你的代码是否会/不会生成警告
Test::Deep - 深度比较对象。它们不必完全相同,你可以忽略数组顺序,使用正则表达式,忽略对象类等。
Test::Pod - 确保你的脚本有POD(文档),并且它是有效的
Test::Pod::Coverage - 确保你的POD文档中涵盖了模块中所有的方法/函数
Test::DBUnit - 测试数据库交互
Test::MockObject - 制作虚假对象来控制测试环境
以下是一些反建议:
反建议:
不要使用Perl的Test::Unit
测试包系列,例如Test::Unit::Assert
和Test::Unit::TestCases
。
原因:Test::Unit
似乎已被放弃。
Test::Unit、Test::Unit::TestCases、Test::Unit::Assert在2015-2016年期间使用效果相当好。虽然Test::Unit据说没有与Perl的测试任何协议(TAP)集成,但我发现很容易修复这个问题。
但是,Test::Unit令人沮丧,因为许多其他Perl测试包大多数都是使用Test::Builder构建的,如Test::More、Test::Most、Test::Exception、Test::Differences、Test::Deep、Test::Warn等,这些测试包与Test::Unit的面向对象测试方法不兼容。
当你将Test::Unit适配到Test::More和TAP上时,可以混合使用Test::Unit测试和Test::Builder测试;但是这些其他包的好特性对于OO扩展不可用。这也是使用xUnit风格测试的主要原因之一。
据说CPAN的Test::Class
允许“轻松创建xUnit/JUnit风格的测试类”——但我不确定是否可以推荐这个。它肯定不像xUnit——没有面向对象,名称很奇怪,例如is(VAL1,VAL2,TESTNAME)
,而不是像$test_object->assert_equals(VAL1,VAL2,TEST_ERR_MSG)
那样的xUnit风格名称。Test::Class具有自动检测所有标注为:Test的测试的良好特性,类似于xUnit和TEST::Unit::TestCase使用内省运行所有命名为test_*函数的方法。
但是,底层包Test::Builder
是面向对象的,因此更符合xUnit风格。不要被名称吓到——它不是一个工厂,它主要是一个带有测试断言方法的套件。虽然大多数人都从中继承,但如果您愿意,也可以直接调用它,例如$test_object->is(VAL1,VAL2,TESTNAME)
,通常可以使用Test::Builder调用来解决建立在Test::Builder之上的过程式包(如Test::More)的限制,例如修复报告错误的调用堆栈级别。
Test::Builder通常以单例模式使用,但可以创建多个对象。我不确定这些对象是否像xUnit系列测试一样表现。
到目前为止,还没有简单的方法来解决限制,例如Perl TAP测试使用TEST_NAMES,每个断言一个,没有层次结构,并且不能区分TEST_NAMES和TEST_ERROR_MESSAGES。(错误报告级别有助于解决这个问题。)
可能可以创建一个适配器,使Test::Builder和TAP样式的测试更加面向对象,以便您可以在除TAP之外的其他东西上重新定位(记录比TAP更有用的信息 - 据说类似于ANT的XML协议)。我认为要适应名称和/或缺失的概念将涉及进入Test::Builder或内省。
Test2::V0是Test::More
的续集...
...以及来自Test2::Harness
的yath命令,是prove的续集。
有一定程度的向后兼容性,值得一看。
use Test::More 'no_plan'
或在脚本末尾调用done_testing()
。 - rjhperl -v
命令可以提供Perl版本,而你可以通过perl -MTest::More -e "print Test::More->VERSION()"
命令获取Test::More版本。无论哪种方式,如果可能的话最好有一个计划。起初我发现这很烦琐,但后来当测试在中途意外死亡时,并且没有报告我的几个测试用例时,这成为了一个救命稻草。如果不是这个计划,我将永远不会知道存在问题。 - Robert Pdone_testing;
пјҢ然еҗҺзҙ§и·ҹзқҖuse Test::More;
еҚіеҸҜжӯЈеёёе·ҘдҪңгҖӮеҗҰеҲҷпјҢжӮЁйңҖиҰҒдҪҝз”Ёuse Test::More qw(no_plan)
гҖӮ - rjhTest::
模块都可以一起使用。例如,Test::More
可以与Test::Differences
、Test::Deep
等组合使用。 - Schwern