Как запустить несколько, но не все тесты в наборе тестов Perl параллельно?

У меня есть набор тестов на основе Perl с 10 000 + тестами, которые я бы хотел сделать быстрее. Я тестировал с использованием флага -j в prove, и я обнаружил, что большинство тестов, но не все, готовы к параллельному запуску.

В то время как я могу работать над тем, чтобы остальные тесты были "дружественными друг к другу", я ожидаю, что всегда будут какие-то тесты, которых нет. Какой хороший способ справиться с этим? Я бы хотел, чтобы это было легко эффективно запускать весь набор тестов и упростить оценку тестов как "непараллельно-готовых", если мне нужно.

Вот некоторые варианты, которые я вижу:

Я не слишком обеспокоен тем, как я буду управлять списком исключений. Либо я могу сохранить список в файле как часть инфраструктуры тестового жгута, либо я мог бы поместить что-то в каждый тестовый заголовок, который бы обозначил его как таковой, и наш тестовый жгут мог динамически определять список исключений.

(Набор тестов частично основан на Test:: Class, и я также буду искать Test:: Class:: Load, чтобы ускорить его.)

Ответы

Ответ 1

Я нашел решение. Это в документации для aggregate_tests() для 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, который позволит вам указать файл, который содержит список тестовые файлы должны быть исключены из параллельного тестирования.

UPDATE 2012-08-16: Теперь у меня есть патч для prove и отправил его для просмотра. Вы можете просмотреть и прокомментировать запрос Pull. После выхода прогона не создается сводка. Не понятно почему.

Ответ 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, который добавляет документацию для этой функции, и начал обсуждение о возможно более простом синтаксисе для основных исключений. Подробнее см. Запрос на извлечение.

Ответ 3

Я нашел другое решение, которое рекламировало эту функцию, но я мог только получить тривиальные случаи для работы. Это использовать Test:: Steering. Это позволяет мне сделать это:

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

С помощью этого решения помните:

  • Прежде чем он действительно работает, я в настоящее время должен исправить код, чтобы исправить базовую ошибку, которая осталась не загруженной в течение нескольких лет.
  • Дополнительный код необходим для обработки списка параллельных и последовательных тестов для запуска.
  • На самом деле я не получил сводного резюме для моего реального теста... оба раздела выпустили свои сводные отчеты, поэтому на самом деле это не работало. Возможно, я что-то пропустил или, может быть, сломался.

Ответ 4

Test:: Parallel также обеспечивает более простой способ параллельного запуска некоторых тестов взгляните на образец из https://metacpan.org/pod/Test::Parallel

Ответ 5

Другой вариант: используйте файл правил для TAP::Harness.

Вы можете создавать пользовательские правила в файле YAML (по умолчанию - testurules.yml). Мне было нужно что-то похожее на то, что вы описали, что я смог сделать с файлом 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
            - **

В моем случае я использовал это с кодом, который напрямую назывался App:: Prove, а не командной строки prove. Но я думаю, что он будет работать и с prove?