Perl的首选单元测试框架是什么?

unguejic  于 2023-03-09  发布在  Perl
关注(0)|答案(6)|浏览(212)

我是Perl的新手,我想知道是否有更好的单元测试框架?
谷歌给我展示了一些不错的结果,但由于我是新手,我不知道社区内是否有明确的偏好。

68bkxrlz

68bkxrlz1#

Perl有一个庞大的测试工具集!Perl核心有几万个自动化的检查程序,它们大多使用这些标准的Perl框架。它们都是通过TAP -Test Anything Protocol,捆绑在一起的。
在Perl中创建TAP测试的标准方法是使用Test::More系列包,包括Test::Simple作为入门。

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.

基本上,要开始,您所需要做的就是put pass一个布尔值和一个解释应该发生什么的字符串!
一旦你通过了这一步,Test::More有大量的其他函数来简化其他测试(字符串、正则表达式比较、深层结构比较),还有Test::Harness后端,可以让你一起测试大量的单独测试脚本。
最重要的是,正如Schwern所指出的,几乎所有的现代Test::模块都可以一起工作,这意味着可以使用Test::Class(正如Markus所指出的)与rjh的答案中列出的所有伟大的模块。事实上,因为Test::Builder--Test::More和其他产品的构建工具(目前由Schwern维护...谢谢Schwern!)--如果需要,您可以从头开始构建你自己的测试子程序,它可以和所有其他的测试框架一起工作。在我看来,仅这一点就使Perl的TAP系统成为最好的测试框架之一:所有的东西一起工作,每个人都使用相同的工具,并且您可以添加到框架中以满足您的需要,而只需要很少的额外工作。

ljsrvy3e

ljsrvy3e2#

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

可以使用Test::More为各种条件生成TAP-检查变量是否等于某个值,检查模块是否正确导入,或者检查是否有两个结构(数组/散列)是相同的,但在真正的Perl精神中,有不止一种方法可以做到这一点,还有其他方法(例如Test::Class,它看起来有点像JUnit!)
测试脚本的简单示例(通常以.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');

您可以使用Test::Harness(通常作为prove从shell调用)按顺序运行一系列测试,并获得通过或失败的测试的摘要。
Test::More还可以做一些更复杂的事情,比如将测试标记为TODO(不要期望它们通过,但是运行它们以防万一)或者SKIP(这些测试是中断的/可选的,不要运行它们)。你可以声明你期望运行的测试的数量,这样如果你的测试脚本中途死亡,这可以被检测到。
一旦你开始做更复杂的测试,你可能会发现一些其他的CPAN模块很有用-这里有一些例子,但还有很多(* 许多 *):
Test::Exception-测试代码是否抛出错误/不抛出任何错误
Test::Warn-测试代码是否生成警告
Test::Deep-深入比较对象。它们不必相同-你可以忽略数组排序,使用正则表达式,忽略对象的类等等。
Test::Pod-确保您的脚本具有POD(文档),并且有效
Test::Pod::Coverage-确保POD记录了模块中的所有方法/函数
Test::DBUnit-测试数据库交互
Test::MockObject-创建假装对象以控制测试环境

pdsfdshx

pdsfdshx4#

如果你练习TDD,你会注意到你的单元测试集变化很大。Test::Class遵循xUnit模式(http://en.wikipedia.org/wiki/XUnit)。
对我来说,xUnit的主要好处是将每个测试封装在方法中,框架用测试方法的名称命名每个Assert,并增加了在每个测试之前和之后运行setup-和teardown方法的可能性。
我也尝试过“perl式”的单元测试方法(只是使用Test::More),但我发现它有点过时和麻烦。

5ssjco0h

5ssjco0h5#

一些反建议可能是为了:
反对建议:

不要使用Test::Unit系列的Perl测试包,例如Test::Unit::AssertTest::Unit::TestCases

原因:Test::Unit似乎已被放弃。
Test::Unit,Test::Unit::TestCases,Test::Unit::Assert工作得很好(当我在2015-2016年使用它们时)。Test::Unit应该没有与Perl的Test Anything Protocol(TAP)集成,尽管我发现这很容易修复。
但是Test::Unit是令人沮丧的,因为许多其他的Perl测试包,大多数是使用Test::Builder构建的,比如Test::More、Test::Most、Test::Exception、Test::Differences、Test::Deep、Test::Warn等,都不能很好地与Test::Unit的面向对象测试方法交互。
您可以混合Test::Unit测试和Test::Builder测试,只要您调整了Test::Unit以与Test::More和TAP一起使用;但是其他包的好特性不适用于OO扩展,这也是使用xUnit风格测试的主要原因。
假设CPAN的Test::Class允许“以xUnit/JUnit样式轻松创建测试类”--但我不确定我是否可以推荐这个。在我看来,它肯定不像xUnit--不是OO,像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风格。不要被这个名字吓到--它不是一个工厂,它主要是一个带有测试Assert方法的套件。尽管大多数人都是从它继承的,但如果你愿意,你可以直接调用它,例如$test_object->is(VAL1,VAL2,TESTNAME),而且通常你可以使用Test::Builder调用来解决构建在Test::Builder之上的过程包(如Test::More)的限制--比如修复报告错误的调用堆栈级别。
Test::Builder通常以单例样式使用,但您可以创建多个对象。我不确定这些对象的行为是否与xUnit家族测试所期望的一样。
到目前为止,还没有一种简单的方法来解决限制,例如Perl TAP测试使用TEST_NAMES,每个Assert都使用,没有层次结构,也没有区分TEST_NAMES和TEST_ERROR_MESSAGES(错误报告级别有助于解决这个问题)。
可以创建一个适配器,使Test::Builder和TAP样式的测试更加面向对象,这样您就可以基于TAP以外的其他东西(记录比TAP更有用的信息--可能像ANT的XML协议)。我认为修改名称和/或缺失的概念将涉及到进入Test::Builder或自省。

kxxlusnw

kxxlusnw6#

Test2::V0是Test::的续集更多...
...以及Test2::Harness中的yath命令,这是要证明的结果。
有一定程度的向后兼容性,所以值得一看。
https://metacpan.org/pod/Test2::Manual

相关问题