如何在 Perl 测试套件中并行运行一些但不是所有测试?
Posted
技术标签:
【中文标题】如何在 Perl 测试套件中并行运行一些但不是所有测试?【英文标题】:How to run some but not all tests in a Perl test suite in parallel? 【发布时间】:2012-08-15 20:47:07 【问题描述】:我有一个基于 Perl 的测试套件,其中包含 10,000 多个测试,我想让它们运行得更快。我已经使用-j
标志对prove
进行了测试,我发现我的大多数但不是所有测试都准备好并行运行。
虽然我可以努力使其余测试“并行友好”,但我希望总有一些测试不是。有什么好的方法来管理这个?我希望它能够轻松高效地运行整个测试集,并在需要时轻松将测试标记为“未准备好”。
以下是我看到的一些选项:
-
prove could be patched to support some tests as not-parallel-ready
Jenkins 被用于管理测试套件的运行。我可以将非并行测试拆分为他们自己的运行。换句话说,放弃并使用两次测试运行。
也许有一种方法可以将两个
TAP
结果流合并在一起,但我还没有恢复。
我不太关心如何管理例外列表。我可以在文件中保留一个列表作为测试工具基础设施的一部分,或者我可以在每个测试标头中放置一些东西来标记它,我们的测试工具可以动态确定异常列表。
(测试套件部分基于 Test::Class,我还将研究 Test::Class::Load 以加快它的速度。)
【问题讨论】:
【参考方案1】:我找到了解决方案。它在aggregate_tests() for 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);
从那里看起来我可以:
子类App::Prove
并覆盖 _runtests()
,这是可以合并上述新功能的地方。
fork prove
以便它调用 My::App::Prove
而不是 App::Prove
。
现在我更好地理解了这些部分是如何组合在一起的,我可以看到如何为prove
创建一个补丁,它会添加一个像--exclude-from-parallel FILE
这样的选项,它允许你指定一个文件,其中包含一个列表要从并行测试中排除的测试文件。
2012-08-16 更新:我现在有一个针对 prove
的补丁,并已提交以供审核。你可以view and comment on the Pull Request。运行输出后不生成摘要。目前尚不清楚为什么。
【讨论】:
【参考方案2】:到目前为止,我已经找到了解决此问题的最佳方法。事实证明,prove
自 2008 年以来一直支持将一些测试标记为按顺序运行而不是并行运行。它由 TAP::Parser::Scheduler 中一个相当花哨的“规则”系统支持,该系统允许复杂的规范并行和顺序测试运行的订购安排。
这是prove
的基本当前配方:
# All tests are allowed to run in parallel, except those starting with "p"
--rules='seq=t/p*.t' --rules='par=**'
我有一个新的pull request,它为这个特性添加了文档,并且已经开始讨论可能为基本异常提供更简单的语法。有关详细信息,请参阅拉取请求。
【讨论】:
【参考方案3】:我找到了另一个宣传此功能的解决方案,但我只能让琐碎的案例发挥作用。使用Test::Steering。它允许我这样做:
include_tests( jobs => 4 , @parallel_tests );
include_tests( @serial_tests );
使用此解决方案,请注意:
在它真正起作用之前,我目前必须 patch the code to fix a basic bug 使用它多年来一直没有打补丁。 需要额外的代码来处理生成要运行的并行和串行测试列表。 我实际上并没有得到我真实世界测试的综合总结......两个部分都发出了自己的总结报告,所以它并没有真正起作用。也许我错过了什么,或者它坏了。【讨论】:
【参考方案4】:Test::Parallel 还提供了一种更简单的方法来并行运行一些测试 看看来自https://metacpan.org/pod/Test::Parallel的样本
【讨论】:
除了这不是在我的环境中构建的:(。它也非常复杂。我在大约一个小时内实现了一个更简单的解决方案,其中包含一些分叉和构建器->输出。如果我很乐意发布到 CPAN任何人都想要它。【参考方案5】:另一种选择:为TAP::Harness 使用规则文件。
您可以在 YAML 文件(默认称为 testrules.yml)中构建自定义规则。我需要类似于你描述的东西,我可以用一个看起来像这样的 testrules.yml 文件来做到这一点:
--- 序列: # 未准备好并行的测试(将单独运行) - 序列: -t/test1.t - t/test2.t # 可以并行运行的测试 - 标准杆: # 其他所有内容的通配符 - **在我的例子中,我将它与直接调用 App::Prove 的代码一起使用,而不是命令行 prove
。但我认为它也适用于prove
?
【讨论】:
以上是关于如何在 Perl 测试套件中并行运行一些但不是所有测试?的主要内容,如果未能解决你的问题,请参考以下文章
如何在机器人框架中并行运行多个测试套件上的多个测试用例 | Python