简体   繁体   English

如何并行运行Perl测试套件中的一些但不是所有测试?

[英]How to run some but not all tests in a Perl test suite in parallel?

I've got a Perl-based test suite with 10,000+ tests that I would like to make run faster. 我有一个基于Perl的测试套件,有10,000多个测试,我想让它运行得更快。 I've tested using the -j flag to prove , and I have found that most-but-not-all of my tests are ready to run in parallel. 我已经使用-j标志进行了测试来prove ,我发现大多数但并非所有的测试都准备好并行运行。

While I can work on making the remaining tests to be "parallel friendly", I expect there always be some tests which are not. 虽然我可以努力使其余的测试“并行友好”,但我希望总有一些测试不是。 What's a good way to manage this? 管理这个的好方法是什么? I would like for it to be easy to run the whole set of tests efficiently, and make it easy to mark tests as "not-parallel-ready" if I need to. 我希望能够有效地运行整套测试,并且如果需要的话,可以很容易地将测试标记为“非并行就绪”。

Here are some options I see: 以下是我看到的一些选项:

  1. prove could be patched to support some tests as not-parallel-ready 证明可以修补以支持一些非并行准备的测试
  2. Jenkins is being used to manage the test suite runs. Jenkins被用来管理测试套件运行。 I could split off the non-parallel tests into their own run. 我可以将非并行测试分解为自己的运行。 In other words, give up and use two test runs. 换句话说,放弃并使用两次测试运行。
  3. Perhaps there is a way to merge two TAP result streams together that I have yet to recover. 也许有一种方法可以将两个TAP结果流合并到一起,我还没有恢复。

I'm not too concerned with how I will manage the list of exceptions. 我不太关心如何管理例外列表。 Either I can keep a list in a file as part of the test harness infrastructure, or I could put something in each test header that would mark it as such, and our test harness could determine the list of exceptions dynamically. 要么我可以将列表作为测试工具基础结构的一部分保存在文件中,要么我可以在每个测试标题中放置一些标记它的内容,并且我们的测试工具可以动态地确定异常列表。

( The test suite is partially based on Test::Class, and I'll also be looking at Test::Class::Load to speed it up as well. ) (测试套件部分基于Test :: Class,我也会看看Test :: Class :: Load来加速它。)

I found a solution. 我找到了解决方案。 It's in the documentation for aggregate_tests() for TAP::Harness . 它位于TAP :: Harness的aggregate_tests()文档中。 It includes a code sample for how I could write my own harness for this purpose: 它包含一个代码示例,用于说明如何为此目的编写自己的线束:

...This is useful, for example, in the case where some tests should run in parallel but others are unsuitable for parallel execution. ...例如,在某些测试应并行运行但其他测试不适合并行执行的情况下,这很有用。

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);

From there it looks like I could: 从那里看起来我可以:

  • Sub-class App::Prove and override _runtests() , which is where the new functionality above could be merged in. 子类App::Prove并覆盖_runtests() ,这是上面的新功能可以合并的地方。
  • Fork prove so that it calls My::App::Prove instead of App::Prove . fork prove它调用My::App::Prove而不是App::Prove

Now that I better understand how the pieces fit together I can see how I might create a patch for prove that would add an option like --exclude-from-parallel FILE , which would allow you to specify a file, which contains a list of test files to be excluded from parallel testing. 现在我更好地理解这些部分是如何组合在一起的,我可以看到我如何创建一个补丁来prove可以添加一个像--exclude-from-parallel FILE这样的选项,这将允许你指定一个文件,其中包含一个列表测试文件要从并行测试中排除。

UPDATE 2012-08-16: I have a patch for prove now, and have submitted it for review. 更新2012-08-16:我现在有一个补丁prove ,并已提交审查。 You can view and comment on the Pull Request . 您可以查看和评论Pull请求 No summary is produced after the run output. 运行输出后没有生成摘要。 It's not clear why. 目前尚不清楚为什么。

I've now found the best solution so far to this problem. 到目前为止,我已经找到了解决这个问题的最佳解决方案。 In turns out that prove has had undocumented support for marking some tests to be run in sequence instead of parallel since 2008. It's backed by a rather fancy "rules" system in TAP::Parser::Scheduler that allows for complex specifications of ordering arrangements for parallel and sequential test runs. 事实prove ,自2008年以来, prove已经没有文件支持标记一些测试按顺序而不是并行运行。它由TAP :: Parser :: Scheduler中一个相当花哨的“规则”系统支持,允许复杂的订购安排规范用于并行和顺序测试运行。

Here's the basic current recipe for prove : 这是prove的基本当前配方:

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

I have a new pull request that adds documentation for this feature, and have started a discussion about possibly offering a simpler syntax for basic exceptions as well. 我有一个新的pull请求 ,为此功能添加了文档,并开始讨论可能为基本异常提供更简单的语法。 See the pull request for details. 有关详细信息,请参阅pull请求。

I found another solution which advertised this feature, but I could only get trivial cases to work. 我找到了另一个宣传这个功能的解决方案,但我只能处理琐碎的案例。 It's to use Test::Steering . 这是使用Test :: Steering It allows me to do this: 它允许我这样做:

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

With this solution, be aware: 有了这个解决方案,请注意:

  • Before it actually works, I currently have to patch the code to fix a basic bug with it that has remained unpatched for multiple years. 在它真正起作用之前,我目前必须修补代码来修复一个基本错误 ,它已经多年未修补。
  • Additional code is needed to handle generating the list of of parallel and serial tests to run. 需要额外的代码来处理生成要运行的并行和串行测试的列表。
  • I didn't actually get a combined summary for my real-world test... both sections emitted their own summary reports, so it didn't really work. 我实际上没有得到我的真实世界测试的综合摘要......两个部分都发布了他们自己的摘要报告,所以它没有真正起作用。 Maybe I missed something, or maybe it's broken. 也许我错过了一些东西,或者它可能已经坏了。

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

Another option: use a rules file for TAP::Harness . 另一种选择:使用TAP :: Harness的规则文件。

You can build custom rules in a YAML file (called testrules.yml by default). 您可以在YAML文件中构建自定义规则(默认情况下称为testrules.yml)。 I needed something similar to what you describe, which I was able to do with a testrules.yml file that looked like this: 我需要类似于你所描述的内容,我可以用testrules.yml文件看起来像这样:

---
    seq:
        # tests that are not parallel-ready (will run in isolation)
        - seq:
            - t/test1.t
            - t/test2.t
        # tests that can run in parallel
        - par:
            # wildcard for everything else
            - **

In my case, I was using this with code that directly called App::Prove, rather than command-line prove . 在我的情况下,我使用的代码直接调用App :: Prove,而不是命令行prove But I think it would work with prove too? 但我认为这也适用于prove

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM