Skip to content

Test suite optimization#1

Open
foxy-eyed wants to merge 1 commit intospajic:masterfrom
foxy-eyed:test-suite-optimization-report
Open

Test suite optimization#1
foxy-eyed wants to merge 1 commit intospajic:masterfrom
foxy-eyed:test-suite-optimization-report

Conversation

@foxy-eyed
Copy link

@foxy-eyed foxy-eyed commented May 19, 2019

Задание №7: Оптимизация Test Suite и сбор DX-метрик

Код здесь: foxy-eyed/task-3#2

Несколько первых прогонов завершились за время в интервале ~ 800–1000 секунд.

  1. Включение parallel_tests c TEST_ENV_NUMBER=2 снизило время прогона до 385 секунд.

  2. Избавившись от загрузок в фабрике users, сократили время до 365 секунд.

  3. Построила отчёт stackprof для самой медленной группы из отчёта rspec --profile (./spec/controllers/internal_users_controller_spec.rb – 104 cекунды).
    Кстати, для генерации отчёта в формате json требуется обновить гем test-prof.
    Попробовала воспользоваться инструментом speedscope.app для анализа полученного json-файла, подтвердила выводы, известные по итогам вебинара 😅
    Отключение Honeycomb в Airbrake в тестовом окружении позволило сократить время прогона тестов до 285 сек.

  4. Оптимизация топ самых медленных тестов из отчёта RSpecDissect с помощью хелперов let_it_be и before_all снизила время прогона до 225 секунд.

  5. Отчёт FactoryDoctor показал, что потенциально "плохих" тестов 98 штук, а возможная экономия времени составит 10 секунд. Не стала связываться, потому что структура тестов затрудняет рефакторинг, а потенциальная польза не очень существенная.

  6. Построила отчёт FactoryFlame. На картинке видно, что фабрика user всегда создает вместе с собой каскадом identity, всего более 1700 раз.
    Вынесла создание identity в trait, который используется точечно. В результате flamegraph изменился таким образом:

    До:
    FactoryFlame_before
    После:
    FactoryFlame_after

    Весь test suite прогнался за 213 секунд.

  7. Дальше с помощью инстумента EventProf построила отчёт для события factory.create для всего test suite.
    На первом месте по продолжительности: ./spec/features/user_views_a_reading_list_spec.rb.
    Для этой группы сгенерировала flamegraph:
    $ FPROF=flamegraph bin/rspec spec/features/user_views_a_reading_list_spec.rb

    user_views_a_reading_list_spec_before

    Это feature-тест для раздела Reading List, куда попадают сохраненные пользователем статьи (при этом создается модель Reaction). Сами тесты проверяют наличие на странице элемента типа "Загрузить ещё", который появляется только когда статей больше чем параметр PER_PAGE=45. Соответственно, создаются 46 Reaction + 46 Article + 46 User (авторы) для одного теста.

    • Для тестового окружения изменила константу PER_PAGE с 45 до 4.
    • Использовала FactoryDefault для генерации статей (одна фабрика пользователя в качестве автора).
      flamegraph после оптимизации:
    user_views_a_reading_list_spec_after

    Итог для данного теста: 18.24 -> 5.36 сек.
    Итог по test suite: 205 сек.

  8. Избавление от database_cleaner + use_transactional_fixtures
    Сначала я планировала убрать database_cleaner из юнит-тестов, но оставить его для feature-тестов. Но потом решила попробовать мигрировать на системные тесты, которые идут с рельсами "из коробки".

    Краткое содержание квеста:

    • Поменять настройку config.use_transactional_fixtures = true.
    • Удалить database_cleaner и все его упоминания в коде.
    • Удалить chromedriver-helper. Могут возникнуть проблемы с chromedriver и rbenv (мне пришлось переустановить https://medium.com/fusionqa/issues-with-rbenv-and-chromedriver-990bb14aa57a).
    • Для решения конфликта версий capybara пришлось обновить рельсу до 5.2 ради этого коммита rails/rails@72f17d5
    • У тестов заменить тип feature на тип system.
    • Указать/сконфигурировать драйверы (итоговые настройки для системных тестов вынесла в отдельный файл).
    • Не забыть поменять тип при подключении хелперов Devise: config.include Devise::Test::IntegrationHelpers, type: :system

Результат по метрикам хороший: 183 сек.

Сами системные тесты даже отрабатывают с минимальными изменениями без особых падений. Проблема возникла, что странно, с некоторыми unit-тестами, причем с теми, что не были затронуты рефакторингом, и я это связываю с обновлением Rails.

Попытки выборочно пофиксить их не привели меня к успеху, нужно закапываться очень глубоко. В частности, есть обоснованные предположения, что отвалились какие-то сайд-эффекты, происходящие в колбеках моделей и т.п. Кажется, что unit-тесты, допустим, моделей, должны изолированно работать с моделью, и не надо бы им падать из-за всякой внешней ерунды 😅. И коду бы ломаться не надо) Иллюстрирует!

Откатывать не стала, потому что:

  • Прирост скорости заметный
  • Стратегически шаг верный

График изменения метрики из Chronograf:

Chronograf_report

@foxy-eyed foxy-eyed marked this pull request as ready for review May 21, 2019 17:35
@foxy-eyed foxy-eyed changed the title [WIP] Test suite optimization Test suite optimization May 21, 2019
@spajic
Copy link
Owner

spajic commented May 22, 2019

Великолепно!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants