Почему мои тесты Minitest не выполняются параллельно?
Я только недавно понял, что мои тесты Minitest могут работать параллельно. Все, что мне нужно было сделать, это
require "minitest/hell"
и я так и сделал. К сожалению, мои тесты работают так же, как и раньше. Все проходит, и это занимает ровно столько времени, сколько обычно. Я проверил htop
во время работы моего набора тестов, и используется только одно ядро.
Я установил точку останова в случайном тесте, чтобы проверить, были ли тесты настроены на параллельное выполнение:
(byebug) Minitest:: Test.test_order:параллельно
Так, что происходит?
Моим первым предположением было то, что Minitest подсчитывает количество ядер ЦП, когда решает, сколько процессов порождать. У меня было несколько физических процессоров (на виртуальной машине), но по одному ядру на процессор. Я изменил свой VPS, чтобы иметь два физических процессора, каждый с 4 ядрами, и мои тесты все еще не выполняются параллельно.
$ lscpu Архитектура: x86_64 Операционные режимы процессора: 32-разрядный, 64-разрядный Порядок байтов: Little Endian ЦП: 8 Он-лайн список процессоров: 0-7 Резьба (ы) на ядро: 1 Сердечник (и) на сокет: 4 Разъем (ы): 2 NUMA узел (ы): 1 Идентификатор поставщика: GenuineIntel Семейство процессоров: 6 Модель: 62 Степпинг: 4 МГц процессора: 2600.000 BogoMIPS: 5200,00 Поставщик гипервизора: VMware Тип виртуализации: полная L1d кеш: 32K L1i кеш: 32K Кэш-память второго уровня: 256 КБ Кэш-память третьего уровня: 20480 КБ NUMA узел0 ЦП: 0-7
3 ответа
Minitest использует потоки, а не процессы для параллельного выполнения теста.
Поскольку MRI (стандартный интерпретатор Ruby) имеет глобальную блокировку интерпретатора, одновременно может выполняться только один поток. Поэтому ваши тесты не работают параллельно при использовании МРТ.
Вы можете настроить параллельное выполнение тестов с помощью интерпретатора Ruby, который поддерживает параллельные потоки, такие как JRuby или Rubinius.
Ответ Северина о том, что МРТ не может выполняться параллельно из-за GIL, является правильным. (Отказ от ответственности: я написал статью, на которую он ссылается.) Во многих рецензиях язык становится немного размытым, но вы можете прочитать эту статью для очень простого описания.
Если вы по-прежнему заинтересованы в параллельном выполнении тестов и не можете изменить интерпретаторы Ruby, взгляните на гем parallel_tests в качестве альтернативы, хотя и с некоторыми ограничениями.
Для параллельного запуска тестов вам нужна либо версия Ruby, которая обеспечивает параллельное выполнение (например, JRuby), либо вы можете использовать простые команды оболочки для запуска нескольких запусков minitest.
Например, используйте GNU параллельно:
find test -type f | parallel --dry-run bundle exec rake test TEST={}
(The dry-run
флаг, чтобы вы могли видеть, что происходит, прежде чем запустить его; опустить dry-run
Отметьте, когда вы удовлетворены, команды будут делать то, что вы хотите.)
Накладные расходы на bundle exec и rake очень высоки. Основное преимущество параллельного выполнения состоит в том, чтобы гарантировать, что ваши тесты ведут себя правильно - то есть основное преимущество не в скорости. Если вы используете параллельный, вы, вероятно, захотите попробовать spork
который держит предварительно разогретое приложение готовым.