Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HomeWork7 Profile & Optimize tests #19

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions case-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Оптимизация test-suite и сбор DX-метрик

## Проблема

У нас в проекте всеь сьют тестов прогоняется за 6,5 минут. Мы уже используем библиотеку test-prof, для оптимизации производительности, но начали использовать ее относительно недавно, так что есть простор для оптимизаций. Также у нас отключено логирование в тестовом окружении.

## Подготовка

### Step 1. Подключение influxdb

1. Подключил гем 'influxer'
2. Поднял в докере `[email protected]:influxdata/TICK-docker.git`
3. Настроил influxdb.yml файл

### Step 2. Настройка сбора метрики

1. Создал рейк задачу, которая будет запускать тесты, замерять их время выполнения и отправлять данные в хронограф.
2. Создал класс в проекте, отнаследованный от Influxer::Metrics через который будет осуществляться управление метрикой.

### Step 3. Первичная прогонка тестов

Прогнал весь сьют.

### Оптимизация

### Step 1. FactoryDoctor

Я раньше не использовал этот инструмент. Решил посмотреть на его отчет
Прогнал с этой настройкой на всем сьюте, и нашел в отчете самую жирную тест группу `(161 records created, 00:01.224)`
Это были тесты на возможности пользователя с определенной ролью (cancancan), посмотрев внутря я увидел конечно же `FactoryBot.create` внутри `let`
Но для тестирования abilite, совсем не нужно создавать запись в базе. Поэтому я заменил все `FactoryBot.create` на `FactoryBot.build`, а также модифицировал один трейт в одной из фабрик, и там также изменил create association на build association.
FactoryDoctor сказал что все теперь хорошо с этими тестами. Секономили чуть больше секунды времени, и перестали дергать базу без необходимости.

### Step 2. Rspec --profile

Позапускал тесты с семплированием и профилированием. Нашел медленный тест, выполняющийсей стабильно примерно за 0.7 сек.
Выяснилось, что это совсем устаревшее апи (которое пока еще не выпилили), для которого мы зачем-то до сих пор гоняем тесты.
Нужно будет обсудить с командой, что делать с этими тестами. Старое АПИ пока выпилить не можем (только через 2-3 месяца). С одной стороны уменьшать покрытие не хорошо, с другой стороны, зачем нам покрытие кода, которым сейчас практически никто не пользуется, и который уже точно не будет меняться.
В любом случае оптимизировать уже почти мертвые тесты наверное не стоит.

### Step 3. parallel_tests

Установил гем 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 такого небыло.

Скриншот с хронографа [прилагаю](http://joxi.ru/brR9nKjIOyzG0A)

### Результаты.

Прочитал наконец полностью документацию к test-prof. Потрогал FactoryDocktor - вещь хорошая, буду смотреть его отчеты и лечить.
Узнал как делать семплирование и профилирование rspec.
Познакомился с parallel_tests, крутой эффект в производительности по времени, но к сожалению получили рандмно падающие тесты и ошибки с неймспейсингом. К сожалению, с таким поведением, врядли удастся затащить его на CI :(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У нас именно с paralel_test по-моему таких проблем не было, но в целом что-то подобное с конфликтами имён было.
Порешали насколько я помню записью имени класса в виде

class Module1::SomeClass

вместо

module Module1
  class SomeClass

или явным указанием полного имени класса вместе с модулями в тех местах, где могут возникнуть неоднозначности