Ускоряем прогон тестов для Rails + Rspec + Cucumber
Петрунин Максим, 13 ноября 2010 года
Тесты, просто чудесная вещь, но как и многое чудесное имеет свои недостатки. Главный из них – они очень долго выполняются. Сегодня мы рассмотрим два инструмента для улучшения ситуации.
Spork – это инструмент, который позволяет не перегружать тестовое окружение (например, сам Rails, rspec и прочие тестовые библиотеки, которые вы используете), всякий раз, как прогоняется тест. Вместо этого вы запускаете spork (для rspec или unit test) или spork cuc (для cucumber), дожидаетесь, пока он подгрузит окружение, и после этого запускаете ваш rspec или cucumber с ключём --drb
. И они начинают гонять тесты, минуя стадию подгрузки окружения! С настройкой, вы справитесь очень легко.
Да, для Rails 3 вам понадобится rc-версия spork (на данный момент, 0.9.0.rc2), а cucumber + autotest не работают с spork’ом хотя кто-то утверждает, что всё в порядке.
parallel_tests – инструмент, позволяющий распарралелить выполнение тестов (test unit), спек (rspec) или фич (cucumber). Надо понимать, что он запускает параллельно разные файлы, но не отдельные тесты внутри одного файла. Поэтому ускорить выполнение одного большого спека вам не удастся.
Всё, что вам нужно делать, это создать БД как сказано в README, а также после каждой миграции делать rake parralel:prepare
.
Запускать можно как с параметрами по-умолчанию rake parallel:spec
(в этом случае количество процессов определится автоматически по числу ядер), так и указав количество процессов и путь: rake parallel:spec[4,models]
.
Я провёл несколько испытаний. Rspec:
$ date && rake spec:controllers && date
Сбт Ноя 13 14:53:38 MSK 2010
Finished in 58.36 seconds
350 examples, 0 failures
Сбт Ноя 13 14:55:33 MSK 2010
Итого, Rspec утверждает, что справился за 58.36 секунд, а по выводу команды date видно, что потребовалось 115. Т.е. ещё 57 секунд (которые, кстати, мог бы сэкономить spork) потребовалось на загрузку окружений. Кстати, на подгрузку окружения для команды rspec spec/contollers
или для команды bundle exec rspec spec/contollers
тратится около 30 секунд (на bundle на пару секунд дольше).
Посмотрим, на parallel с параметрами по-умолчанию:
$ date && rake rake parallel:spec[controllers] && date
Сбт Ноя 13 14:55:33 MSK 2010
2 processes for 16 specs, ~ 8 specs per process
Finished in 10.39 seconds
184 examples, 0 failures
Finished in 51.1 seconds
166 examples, 0 failures
Results:
166 examples, 0 failures
184 examples, 0 failures
Took 89.216297137 seconds
Сбт Ноя 13 14:57:19 MSK 2010
В первый раз я вывел весь лог, чтобы было понятно, как он выглядит, далее будет короткая выдержка.
Итого: 89.216297137 секунд по словам parralel_test и 106.0 фактических секунд (сэкономлено ~9 секунд). 89 сек – странная цифра, т.к. реальное время выполнения – максимальное из всех процессов, т.е. 51.1, что соответствует экономии в 9 секунд.
$ date && rake rake parallel:spec[4,controllers] && date
Сбт Ноя 13 14:57:19 MSK 2010
4 processes for 16 specs, ~ 4 specs per process
Took 130.743829138 seconds
Сбт Ноя 13 14:59:47 MSK 2010
А вот попытка выполнить на 4_ёх процессах (при реальных 2_ух ядрах) только ухудшила ситуацию: 148.0 – реальных секунд и 130.743829138 заявленных.
Тесты для cucumber:
$ rake cucumber
Сбт Ноя 13 15:26:32 MSK 2010
5m38.088s
Сбт Ноя 13 15:33:09 MSK 2010
Т.е. реальных 6 минут 37 секунд, заявленных 5 минут 38 секунд. Т.е., как и прежде – около минуты на подгрузку окружения.
$ rake parallel:features
Сбт Ноя 13 15:37:28 MSK 2010
Took 268.90437579 seconds
Сбт Ноя 13 15:41:54 MSK 2010
Итого – почти 4 с половиной минуты заявленны, а реальных 4 минуты 50 секунд. Т.е. выигрыш по сравнению с непараллельными тестами 1 минута 47 секунд. Кстати, при прогоне тестов с selenium реально запускаются два сервера и две копии браузера. При этом два сервера могут конфликтовать.
$ rake parallel:features[4]
Сбт Ноя 13 15:41:58 MSK 2010
Took 323.654938436 seconds
Сбт Ноя 13 15:47:39 MSK 2010
Итого на 5:20 заявленных, 5:41 реальных, что всё равно лучше, чем вообще без распарралеливания, но сильно хуже 2 процессов.
К сожалению, spork и parralel_test не работают вместе :(
Итого:
rake spec
вместо rspec scec/
или bundle exec rspec
увеличивает время выполнения теста ~ на 30 секунд. Кстати, parralel_test для Rspec запускаются командой parallel_spec
или bundle exec parallel_spec
(т.е. +30 секунд экономии по сравнению с rake).P.S. Rails 3 + Ruby 1.9.2 + rspec 2.0.1 + cucumber 0.9.3
4 комментария [написать ещё один]
Nice blog here! Additionally your site so much up fast!
What web host are you the usage of? Can I get your affiliate hyperlink on your host?
I desire my website loaded up as fast as yours lol
I got this web site from my pal who informed
me concerning this web site and now this time I am browsing this web page and reading very
informative articles at this place.
Hey There. I found your weblog the usage of msn. That is a very smartly written article.
I will make sure to bookmark it and return to learn more of your useful information. Thank
you for the post. I’ll certainly comeback. Kjøp Lazio
Drakt
Не хватает сводной таблицы.