TAP::Harness - 使用统计信息运行测试脚本
版本 3.44
这是一个简单的测试工具,它允许运行测试并自动汇总结果并输出到 STDOUT。
use TAP::Harness;
my $harness = TAP::Harness->new( \%args );
$harness->runtests(@tests);
new
my %args = (
verbosity => 1,
lib => [ 'lib', 'blib/lib', 'blib/arch' ],
)
my $harness = TAP::Harness->new( \%args );
构造函数返回一个新的 TAP::Harness
对象。它接受一个可选的哈希引用,其允许的键为
verbosity
设置详细程度级别
1 verbose Print individual test results to STDOUT.
0 normal
-1 quiet Suppress some test output (mostly failures
while tests are running).
-2 really quiet Suppress everything but the tests summary.
-3 silent Suppress everything.
timer
将每个测试的运行时间追加到输出。如果可用,则使用 Time::HiRes。
failures
显示测试失败(如果选择了 verbose
,则此操作无效)。
comments
显示测试注释(如果选择了 verbose
,则此操作无效)。
show_count
在测试期间更新正在运行的测试计数。
normalize
设置为真值以规范化在详细模式下发出的 TAP。
lib
接受一个标量值或标量值数组引用,指示在执行 Perl 测试时应包含哪些允许库的路径。当然,这只有在 Perl 编写的测试环境中才有意义。
switches
接受一个标量值或标量值数组引用,指示在执行 Perl 测试时应包含哪些开关。当然,这只有在 Perl 编写的测试环境中才有意义。
test_args
对要传递给每个测试程序的 @INC
样式数组的引用。
test_args => ['foo', 'bar'],
如果要向每个测试传递不同的参数,则应传递一个数组哈希,以每个测试的别名为键。
test_args => {
my_test => ['foo', 'bar'],
other_test => ['baz'],
}
color
尝试生成彩色输出。
exec
通常,Perl 测试通过它运行。但是,任何输出 TAP 的东西都可以。您可以使用此参数指定要运行测试的程序名称(以及可选的开关)。
exec => ['/usr/bin/ruby', '-w']
您还可以传递一个子例程引用,以根据给定的测试脚本确定并返回要运行的正确程序。子例程引用应将 TAP::Harness 对象本身作为第一个参数,并将文件名作为第二个参数。它应该返回一个包含要运行的命令的数组引用,并包含测试文件名。它也可以简单地返回 undef
,在这种情况下,TAP::Harness 将回退到在 Perl 中执行测试脚本。
exec => sub {
my ( $harness, $test_file ) = @_;
# Let Perl tests run.
return undef if $test_file =~ /[.]t$/;
return [ qw( /usr/bin/ruby -w ), $test_file ]
if $test_file =~ /[.]rb$/;
}
如果子例程返回一个带有换行符或文件句柄的标量,它将分别被解释为原始 TAP 或 TAP 流。
merge
如果 merge
为真,则 harness 将创建解析器,这些解析器将为它们启动的任何进程合并 STDOUT 和 STDERR。
sources
3.18 中的新功能.
如果设置,sources
必须是一个包含要加载和/或配置的 TAP::Parser::SourceHandler 名称的哈希引用。这些值是一个配置哈希,这些配置将通过 "TAP::Parser::Source 中的 config_for" 可供源处理程序访问。
例如
sources => {
Perl => { exec => '/path/to/custom/perl' },
File => { extensions => [ '.tap', '.txt' ] },
MyCustom => { some => 'config' },
}
sources
参数会影响 source
、tap
和 exec
参数的处理方式。
有关更多详细信息,请参阅 "TAP::Parser 中的 new"、TAP::Parser::Source 和 TAP::Parser::IteratorFactory 中的 sources
参数。
aggregator_class
用于聚合测试结果的类的名称。默认值为 TAP::Parser::Aggregator。
version
3.22 版本新增.
假设此 TAP 版本用于 TAP::Parser,而不是默认的 TAP 版本 12。
formatter_class
用于格式化输出的类的名称。默认值为 TAP::Formatter::Console,如果输出不是 TTY,则为 TAP::Formatter::File。
multiplexer_class
用于在并行测试期间多路复用测试的类的名称。默认值为 TAP::Parser::Multiplexer。
parser_class
用于解析 TAP 的类的名称。默认值为 TAP::Parser。
scheduler_class
用于安排测试执行的类的名称。默认值为 TAP::Parser::Scheduler。
formatter
如果设置了 formatter
,则它必须是一个能够格式化 TAP 输出的对象。请参阅 TAP::Formatter::Console 以获取示例。
errors
如果在 TAP 输出中发现解析错误,则将在摘要报告中进行说明。要查看所有解析错误,请将此参数设置为 true。
errors => 1
directives
如果设置为 true 值,则仅显示带有指令的测试结果。这将覆盖其他设置,例如 verbose
或 failures
。
ignore_exit
如果设置为 true 值,则指示 TAP::Parser
忽略测试脚本的退出和等待状态。
jobs
任何时候运行的并行测试的最大数量。哪些测试可以并行运行由 rules
控制。默认情况下,一次仅运行一个测试。
rules
对控制哪些测试可以并行执行的规则的哈希的引用。如果未声明任何规则并且 CPAN::Meta::YAML 可用,则 TAP::Harness
尝试从 rulesfile
参数指定的 YAML 文件加载规则。如果不存在规则文件,则默认情况下所有测试都有资格并行运行。
以下是一些简单的示例。有关数据结构和相关 glob 风格模式匹配的完整详细信息,请参阅 "TAP::Parser::Scheduler 中的规则数据结构"。
# Run all tests in sequence, except those starting with "p"
$harness->rules({
par => 't/p*.t'
});
# Equivalent YAML file
---
par: t/p*.t
# Run all tests in parallel, except those starting with "p"
$harness->rules({
seq => [
{ seq => 't/p*.t' },
{ par => '**' },
],
});
# Equivalent YAML file
---
seq:
- seq: t/p*.t
- par: **
# Run some startup tests in sequence, then some parallel tests than some
# teardown tests in sequence.
$harness->rules({
seq => [
{ seq => 't/startup/*.t' },
{ par => ['t/a/*.t','t/b/*.t','t/c/*.t'], }
{ seq => 't/shutdown/*.t' },
],
});
# Equivalent YAML file
---
seq:
- seq: t/startup/*.t
- par:
- t/a/*.t
- t/b/*.t
- t/c/*.t
- seq: t/shutdown/*.t
这是一个实验性功能,接口可能会更改。
rulesfiles
这指定了在哪里查找测试调度规则的 YAML 文件。如果未提供,它会查找要使用的默认文件。它首先检查 HARNESS_RULESFILE
环境变量中给出的文件,然后检查 testrules.yml,最后检查 t/testrules.yml。
stdout
用于捕获标准输出的文件句柄。
陷阱
尝试在运行被 SIGINT (Ctrl-C) 中断时打印摘要信息。
任何值为 undef
的键将被忽略。
runtests
$harness->runtests(@tests);
接受要运行的 @tests
数组。这通常应该是测试文件的名称,但这不是必需的。@tests
中的每个元素将作为 source
传递给 TAP::Parser::new()
。有关更多信息,请参阅 TAP::Parser。
可以通过将测试提供为包含 [ $test, $alias ]
的数组的引用来提供别名,这些别名将在测试名称的位置显示。
$harness->runtests( [ 't/foo.t', 'Foo Once' ],
[ 't/foo.t', 'Foo Twice' ] );
通常,尝试两次运行相同的测试是错误的。别名允许您通过为每次测试运行提供唯一的名称来克服此限制。
测试将按找到的顺序运行。
如果环境变量 PERL_TEST_HARNESS_DUMP_TAP
已定义,它应该命名一个目录,将每个测试的原始 TAP 复制到该目录中。TAP 写入以每个测试命名的文件。子目录将根据需要创建。
返回包含测试结果的 TAP::Parser::Aggregator。
summary
$harness->summary( $aggregator );
输出 TAP::Parser::Aggregator 的摘要。
aggregate_tests
$harness->aggregate_tests( $aggregate, @tests );
运行命名测试并显示结果摘要。测试将按找到的顺序运行。
测试结果将添加到提供的 TAP::Parser::Aggregator 中。aggregate_tests
可以调用多次以运行多组测试。多个 Test::Harness
实例可用于将结果传递给单个聚合器,以便使用不同的 TAP::Harness
设置运行复杂测试套件的不同部分。例如,在某些测试应该并行运行而其他测试不适合并行执行的情况下,这很有用。
my $formatter = TAP::Formatter::Console->new;
my $ser_harness = TAP::Harness->new( { formatter => $formatter } );
my $par_harness = TAP::Harness->new(
{ formatter => $formatter,
jobs => 9
}
);
my $aggregator = TAP::Parser::Aggregator->new;
$aggregator->start();
$ser_harness->aggregate_tests( $aggregator, @ser_tests );
$par_harness->aggregate_tests( $aggregator, @par_tests );
$aggregator->stop();
$formatter->summary($aggregator);
请注意,对于更简单的测试要求,通常可以使用对 runtests
的单个调用来替换上面的代码。
@tests
数组的每个元素都是
要运行的测试的源名称
对 [ 源名称,显示名称 ] 数组的引用
对于 Perl 测试套件,通常情况下,源名称 仅仅是需要运行的测试脚本的文件名。
当您提供一个单独的显示名称时,就可以多次运行同一个测试;显示名称实际上是测试在测试框架内部的别名。测试框架并不关心是否多次运行同一个测试,只要每次调用使用不同的名称。
make_scheduler
当测试框架需要创建一个 TAP::Parser::Scheduler 时,会调用此方法。在子类中重写此方法以提供备用调度器。make_scheduler
会将传递给 aggregate_tests
的测试列表作为参数。
jobs
获取或设置测试框架正在处理的并发测试运行次数。默认情况下,此值为 1 - 对于并行测试,应将其设置为更高的值。
make_parser
创建一个新的解析器和显示格式化程序会话。通常在子类中使用和/或重写。
my ( $parser, $session ) = $harness->make_parser;
finish_parser
终止解析器的使用。通常在子类中使用和/或重写。解析器不会因此而被销毁。
TAP::Harness
被设计为易于配置。
TAP::Parser
插件允许您更改 TAP 的输入 和输出 到解析器的方式。
TAP::Parser::SourceHandler 处理 TAP 的输入。您可以使用 "new" 的 sources
参数来配置它们并加载自定义处理程序。
TAP::Formatter 处理 TAP 的输出。您可以使用 "new" 的 formatter_class
参数来加载自定义格式化程序。要配置格式化程序,您目前需要在 TAP::Harness 之外实例化它,并使用 "new" 的 formatter
参数将其传递进来。这可能 会通过在将来向 "new" 添加一个formatters 参数来解决。
Module::Build
Module::Build 版本 0.30
支持 TAP::Harness
。
要加载 TAP::Harness
插件,您需要使用 tap_harness_args
参数传递给 new
,通常是在您的 Build.PL
中。例如
Module::Build->new(
module_name => 'MyApp',
test_file_exts => [qw(.t .tap .txt)],
use_tap_harness => 1,
tap_harness_args => {
sources => {
MyCustom => {},
File => {
extensions => ['.tap', '.txt'],
},
},
formatter_class => 'TAP::Formatter::HTML',
},
build_requires => {
'Module::Build' => '0.30',
'TAP::Harness' => '3.18',
},
)->create_build_script;
参见 "new"
ExtUtils::MakeMaker
ExtUtils::MakeMaker 不支持 TAP::Harness 开箱即用。
prove
prove 支持 TAP::Harness
插件,并拥有自己的插件系统。有关更多详细信息,请参见 "prove 中的 FORMATTERS"、"prove 中的 SOURCE HANDLERS" 和 App::Prove。
如果您无法配置 TAP::Harness
来执行您想要的操作,并且找不到现有的插件,请考虑编写一个插件。
TAP::Harness 支持的两种主要插件用例是 输入 和 输出
为此,您可以扩展现有的 TAP::Parser::SourceHandler,或编写自己的解析器。这是一个非常简单的 API,可以使用 sources
参数加载和配置它们,以指向 "new"。
为此,您可以扩展现有的 TAP::Formatter,或编写自己的格式化程序。编写格式化程序比编写 SourceHandler 稍微复杂一些,因为您需要了解 TAP::Parser API。一个好的起点是了解 "aggregate_tests" 的工作原理。
可以使用 formatter_class
参数加载和配置自定义格式化程序,以指向 "new"。
如果您无法配置 TAP::Harness
来执行您想要的确切操作,并且编写插件不是一种选择,请考虑扩展它。它被设计为(大部分)易于子类化,尽管子类化必要的案例应该很少见。
如果您想子类化TAP::Harness
,以下方法是您可能希望覆盖的方法。
如果您喜欢prove
实用程序和TAP::Parser,但您想要自己的测试运行器,您只需要编写一个测试运行器并提供new
和runtests
方法。然后,您可以像这样使用prove
实用程序
prove --harness My::Test::Harness
请注意,虽然prove
接受测试列表(或要测试的内容),但new
具有相当丰富的参数集。您可能需要仔细阅读此代码以了解所有参数的使用方式。