У нас в проекте всеь сьют тестов прогоняется за 6,5 минут. Мы уже используем библиотеку test-prof, для оптимизации производительности, но начали использовать ее относительно недавно, так что есть простор для оптимизаций. Также у нас отключено логирование в тестовом окружении.
- Подключил гем 'influxer'
- Поднял в докере
[email protected]:influxdata/TICK-docker.git
- Настроил influxdb.yml файл
- Создал рейк задачу, которая будет запускать тесты, замерять их время выполнения и отправлять данные в хронограф.
- Создал класс в проекте, отнаследованный от Influxer::Metrics через который будет осуществляться управление метрикой.
Прогнал весь сьют.
Я раньше не использовал этот инструмент. Решил посмотреть на его отчет
Прогнал с этой настройкой на всем сьюте, и нашел в отчете самую жирную тест группу (161 records created, 00:01.224)
Это были тесты на возможности пользователя с определенной ролью (cancancan), посмотрев внутря я увидел конечно же FactoryBot.create
внутри let
Но для тестирования abilite, совсем не нужно создавать запись в базе. Поэтому я заменил все FactoryBot.create
на FactoryBot.build
, а также модифицировал один трейт в одной из фабрик, и там также изменил create association на build association.
FactoryDoctor сказал что все теперь хорошо с этими тестами. Секономили чуть больше секунды времени, и перестали дергать базу без необходимости.
Позапускал тесты с семплированием и профилированием. Нашел медленный тест, выполняющийсей стабильно примерно за 0.7 сек. Выяснилось, что это совсем устаревшее апи (которое пока еще не выпилили), для которого мы зачем-то до сих пор гоняем тесты. Нужно будет обсудить с командой, что делать с этими тестами. Старое АПИ пока выпилить не можем (только через 2-3 месяца). С одной стороны уменьшать покрытие не хорошо, с другой стороны, зачем нам покрытие кода, которым сейчас практически никто не пользуется, и который уже точно не будет меняться. В любом случае оптимизировать уже почти мертвые тесты наверное не стоит.
Установил гем parallel_tests. Настроил на 3 потока прогона и получил wow-эффект. Уменьшение времени с 378 сек до 137 секунд. Офигительный эффект в скорости! Жаль только что часть тестов попадало. При ближайшем рассмотрении оказалось, что это из-за конфликтов имен под разными неймспейсами :( Пример:
module Module1
module Module2
class Class1
def some_method
SomeClass.call(...)
end
end
end
end
module Module1
module Module2
class SomeClass
end
end
end
class SomeClass
end
В Class1 вызывается SomeClass, который очевидно что должен быть зарезолвлен изначально в том же самом неймспейсе Module1::Module2::SomeClass, однако при прогоне через parallel_tests класс резолвится от корня ::SomeClass. Причем от прогона к прогону с такой ошибкой могут свалиться разные тесты.
При прогонке через RSpec такого небыло.
Скриншот с хронографа прилагаю
Прочитал наконец полностью документацию к test-prof. Потрогал FactoryDocktor - вещь хорошая, буду смотреть его отчеты и лечить. Узнал как делать семплирование и профилирование rspec. Познакомился с parallel_tests, крутой эффект в производительности по времени, но к сожалению получили рандмно падающие тесты и ошибки с неймспейсингом. К сожалению, с таким поведением, врядли удастся затащить его на CI :(