Как запустить несколько, но не все тесты в наборе тестов 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
?