如何在 Perl 测试套件中并行运行一些测试,但不是全部测试



我有一个基于 Perl 的测试套件,其中包含 10,000+ 个测试,我想让它们运行得更快。我已经使用 -j 标志进行了测试,以prove ,我发现我的大多数(但不是全部)测试都准备好并行运行。

虽然我可以努力使其余的测试"并行友好",但我希望总有一些测试不是。 管理这个问题的好方法是什么?我希望它很容易有效地运行整套测试,并在需要时轻松地将测试标记为"未并行就绪"。

以下是我看到的一些选项:

  1. 证明可以修补以支持某些测试,因为尚未准备好并行
  2. Jenkins 被用来管理测试套件运行。我可以将非并行测试拆分为它们自己的运行。换句话说,放弃并使用两个测试运行。
  3. 也许有一种方法可以将我尚未恢复的两个TAP结果流合并在一起。

我不太关心我将如何管理异常列表。我可以在文件中保留一个列表作为测试工具基础结构的一部分,或者我可以在每个测试标头中放置一些内容来标记它,我们的测试工具可以动态确定异常列表。

(测试套件部分基于 Test::Class,我也将查看 Test::Class::Load 以加快速度。

我找到了解决方案。它位于 TAP::Harness 的 aggregate_tests() 文档中。它包括一个代码示例,用于说明如何为此目的编写自己的工具:

。这很有用,例如,在某些测试应该 并行运行,但其他不适合并行执行。

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(),这是上述新功能可以合并的地方。
  • 分叉prove,以便它调用My::App::Prove而不是App::Prove

现在我更好地了解了这些部分是如何组合在一起的,我可以看到如何为prove创建一个补丁,该补丁将添加一个选项,例如 --exclude-from-parallel FILE ,这将允许您指定一个文件,其中包含要从并行测试中排除的测试文件列表。

更新 2012-08-16: 我现在有一个prove补丁,并已提交审核。您可以查看和评论拉取请求。运行输出后不会生成任何摘要。目前尚不清楚原因。

到目前为止,

我找到了这个问题的最佳解决方案。事实证明,自 2008 年以来,prove一直没有记录支持将某些测试标记为按顺序运行而不是并行运行。它由 TAP::P arser::Scheduler 中一个相当花哨的"规则"系统提供支持,该系统允许为并行和顺序测试运行提供复杂的排序安排规范。

以下是当前prove的基本配方:

 # All tests are allowed to run in parallel, except those starting with "p"
 --rules='seq=t/p*.t' --rules='par=**'

我有一个新的拉取请求,它为此功能添加了文档,并且已经开始讨论可能为基本异常提供更简单的语法。有关详细信息,请参阅拉取请求。

我找到了另一个宣传此功能的解决方案,但我只能让微不足道的情况起作用。这是使用测试::转向。它允许我这样做:

include_tests( { jobs => 4 }, @parallel_tests );
include_tests( @serial_tests  );

使用此解决方案,请注意:

  • 在它实际工作之前,我目前必须修补代码以修复多年来未修补的基本错误。
  • 需要额外的代码来处理生成要运行的并行和串行测试的列表。
  • 实际上没有得到我的真实世界测试的综合摘要......这两个部分都发出了自己的摘要报告,因此它并没有真正起作用。也许我错过了什么,或者它坏了。

Test::P arallel 还提供了一种更简单的方法来并行运行一些测试看看 https://metacpan.org/pod/Test::Parallel 的样本

另一种选择:使用 TAP::Harness 的规则文件。

您可以在 YAML 文件中构建自定义规则(默认情况下称为 testrules.yml)。我需要类似于您描述的内容,我能够使用如下所示的testrules.yml文件执行此操作:

---    以下:        # 非并行就绪的测试(将隔离运行)        - 序:            - t/test1.t            - t/test2.t        # 可以并行运行的测试        -㩱:            # 其他所有内容的通配符            - **

就我而言,我将其与直接调用App::P rove的代码一起使用,而不是命令行prove。但我认为它也适用于prove

最新更新