Ускорение тестов RSpec в большом приложении Rails - PullRequest
90 голосов
/ 08 сентября 2010

У меня есть приложение Rails с более чем 2000 примеров в моих тестах RSpec. Излишне говорить, что это большое приложение, и многое еще предстоит протестировать. Выполнение этих тестов в данный момент очень неэффективно, и, поскольку это занимает так много времени, мы почти отчаиваемся от написания их перед запуском новой сборки. Я добавил --profile к своим spec.opts, чтобы найти самые продолжительные примеры, и есть по крайней мере 10 из них, для выполнения которых требуется в среднем 10 секунд. Это нормально среди вас, экспертов RSpec? 10 секунд слишком долго для одного примера? Я понимаю, что с 2000 примерами потребуется нетривиальное количество времени для тщательного тестирования всего - но на данный момент 4 часа немного смешно.

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

Ответы [ 12 ]

119 голосов
/ 23 февраля 2011

10 секунд - очень длительное время для запуска любого отдельного теста.Я чувствую, что ваша спецификационная задача одновременно выполняет и модульные, и интеграционные тесты.Это типичная вещь, к которой относятся проекты, и на каком-то этапе вам потребуется преодолеть этот технический долг , если вы хотите производить больше и быстрее.Есть ряд стратегий, которые могут помочь вам сделать это ... и я порекомендую несколько, которые я использовал в прошлом.

1.Отдельный блок от интеграционных тестов

Первое, что я хотел бы сделать, это отделить блок от интеграционных тестов.Вы можете сделать это либо:

  1. Переместив их (в отдельные папки в каталоге spec) - и изменив цели для рейка
  2. Пометив их (rspec позволяет пометить ваши тесты)

Философия гласит, что вы хотите, чтобы ваши регулярные сборки были быстрыми, иначе люди не будут слишком рады запускать их часто.Так что возвращайся на эту территорию.Сделайте так, чтобы ваши обычные тесты выполнялись быстро, и используйте сервер непрерывной интеграции для запуска более полной сборки.

Интеграционный тест - это тест, который включает внешние зависимости (например, Database, WebService, Queue, а некоторые утверждают, FileSystem).Модульный тест просто проверяет конкретный элемент кода, который вы хотите проверить.Он должен работать быстро (возможно 9000 за 45 секунд), то есть большая часть должна работать в памяти.

2.Преобразование интеграционных тестов в модульные тесты

Если основная часть ваших модульных тестов меньше, чем набор интеграционных тестов, у вас возникла проблема.Это означает, что несоответствия начнут появляться легче.Итак, начните создавать больше модульных тестов, чтобы заменить интеграционные тесты.Вот что вы можете сделать, чтобы помочь в этом процессе:

  1. Использовать фальшивый фреймворк вместо реального ресурса.В Rspec есть встроенная среда для имитации.
  2. Запустите rcov на вашем модульном тестовом наборе.Используйте это, чтобы оценить, насколько тщателен ваш набор модульных тестов.

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

3.Не используйте светильники

Светильники - зло.Вместо этого используйте фабрику (машинист или factory_girl).Эти системы могут создавать более адаптируемые графики данных, и, что более важно, они могут создавать объекты в памяти, которые вы можете использовать, а не загружать объекты из внешнего источника данных.

4.Добавление проверок для остановки юнит-тестов. Становление интеграционных тестов

Теперь, когда у вас есть более быстрое тестирование, пришло время поставить чеки, чтобы ОСТАНОВИТЬ, чтобы это не повторялось.исправлять активную запись для выдачи ошибки при попытке доступа к базе данных (UnitRecord).

Вы также можете попробовать спаривание и TDD, которые могут помочь вашей команде написать более быстрые тесты, потому что:

  1. Кто-то проверяет - так что никому не лень
  2. Правильный TDD требует быстрой обратной связи.Медленные тесты только делают все это болезненным.

5.Использование других библиотек для преодоления проблемы

Кто-то упоминал spork (ускоряет время загрузки для набора тестов под rails3), hydra / parallel_tests - для параллельного запуска модульных тестов (на нескольких ядрах).

Это, вероятно, следует использовать ПОСЛЕДНЕЕ.Ваша настоящая проблема полностью в шаге 1, 2, 3. Решите это, и вы будете в лучшем положении, чтобы разыграть дополнительную инфраструктуру.

16 голосов
/ 08 сентября 2010

Чтобы получить отличную кулинарную книгу о повышении производительности вашего набора тестов, ознакомьтесь с презентацией Grease Your Suite .

Он документирует ускорение в 45 раз во время выполнения набора тестов, используя такие приемы, каккак:

5 голосов
/ 08 сентября 2010

Вы можете использовать Spork. Поддерживает 2.3.x,

https://github.com/sporkrb/spork

или ./script/spec_server, который может работать для 2.x

Также вы можете редактировать конфигурацию базы данных (что существенно ускоряет запросы к базе данных и т. Д.), Что также увеличивает производительность для тестов.

3 голосов
/ 08 сентября 2010

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

Максимально используйте макеты и заглушки - они намного быстрее, чем пишут код, попадающий в базу данных. К сожалению, издевательства и заглушки также требуют больше времени для написания (и их сложнее сделать правильно). Вы должны сбалансировать время, потраченное на написание тестов, и время, потраченное на выполнение тестов.

Я второй комментарий Эндрю Гримма о поиске системы CI, которая может позволить вам распараллелить ваш набор тестов. Для чего-то такого размера это может быть единственным жизнеспособным решением.

2 голосов
/ 22 декабря 2012

Если вы используете модели ActiveRecord, вам также следует учитывать стоимость шифрования BCrypt.

Подробнее об этом можно прочитать в этом блоге: http://blog.syncopelabs.co.uk/2012/12/speed-up-rspec-test.html

2 голосов
/ 19 мая 2011

Несколько человек упомянули Гидру выше.Мы использовали его с большим успехом в прошлом.Недавно я задокументировал процесс запуска и запуска гидры: http://logicalfriday.com/2011/05/18/faster-rails-tests-with-hydra/

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

1 голос
/ 24 сентября 2010

Оформить заказ на презентацию: http://grease -your-suite.heroku.com / # 1

0 голосов
/ 05 февраля 2016

Удалить существующий набор тестов.Будет невероятно эффективным.

0 голосов
/ 22 января 2016

Вы можете следовать нескольким простым советам, чтобы сначала выяснить, на что тратится большая часть времени, если вы еще не пробовали их. Посмотрите на статью ниже:

https://blog.mavenhive.in/7-tips-to-speed-up-your-webdriver-tests-4f4d043ad581

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

0 голосов
/ 20 сентября 2011

Здесь есть очень общее видео о повышении скорости вашего теста. Может помочь.

...