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

ДЗ №7 #20

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
104 changes: 104 additions & 0 deletions case-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
## Проблема

Проблема: в рабочем проекте медленно проходят тесты:
```
Finished in 5 minutes 25 seconds (files took 20.36 seconds to load)
832 examples, 0 failures, 8 pending
```

## Sidekiq
Прогнал профилировщик:
```
[TEST PROF INFO] EventProf results for sidekiq.inline

Total time: 00:15.767 of 05:27.530 (4.59%)
Total events: 1742
```
Заменил на fake!, зафейлилось много тестов. Решил не стабить sidekiq и вернуть все обратно, ибо это не является самой большой точкой роста.


## DatabaseCleaner
Заметил, что в rails_helper.rb используется DatabaseCleaner:
```
config.before(:suite) do
DatabaseCleaner.strategy = :truncation, { except: %w(spatial_ref_sys) }
DatabaseCleaner.clean
end

config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
```
Закомментировал, получил около 10 фейлящих тестов. Тогда решил вынести флаг для example'ов и вызывать очищение базы явно, где надо:

```
config.before(:each) do |example|
if example.metadata[:database_cleaner]
DatabaseCleaner.strategy = :truncation, { except: %w(spatial_ref_sys) }
DatabaseCleaner.clean
end
end
```
В итоге получил почти двухкратный прирост:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Парам-парам пам!


`
Finished in 2 minutes 45.5 seconds (files took 26.86 seconds to load)
`

## let_it_be, before_all
Запустил RspecDissect для построения отчета, который показал, что во многих suite многократно пересоздаются записи
(в основном это модель User). Тогда я заменил let на let_it_be в топ 5 спеках. Не везде тесты заработали с первого раза,
во многих сущностях пришлось указать let_it_be для связанных полей, еще в нескольких - указать параметр `reload:true`
для перезагрузки записи после мутации из предыдущего теста. В результате:

`
Finished in 2 minutes 28.9 seconds (files took 20.99 seconds to load)
`

Повторный прогон RspecDissect показал, что оставшиеся спеки на время выполнения почти не влияют.

## Оптимизация фабрик
Отчет FactoryProf показал печальную картину:
```
[TEST PROF INFO] Factories usage

Total: 12418
Total top-level: 2659
Total time: 01:39.090 (out of 02:32.893)
Total uniq factories: 21

total top-level total time time per call top-level time name

3109 83 20.2705s 0.0065s 0.6245s interest
3078 0 13.4150s 0.0044s 0.0000s token
1539 1487 128.8310s 0.0837s 124.9127s user
1536 272 13.5771s 0.0088s 2.1966s location
1458 17 7.6440s 0.0052s 0.0899s search_params

...
```

Оказалось, что топ 5 фабрик, которые редко вызываются top-level, связаны с фабрикой User. Тогда я вынес эти связи в trait'ы,
и подключил их только в те примеры, где нужно (связь с Interest оказалась вообще не нужна).
В итоге:

`
Finished in 1 minute 50.2 seconds (files took 20.93 seconds to load)
832 examples, 0 failures, 8 pending
`

## FactoryDoctor
Прогнал отчет FactoryDoctor:
```
[TEST PROF INFO] FactoryDoctor report
Total (potentially) bad examples: 72
Total wasted time: 00:05.538
```
Попробовал заменить в предложенных отчетом тестах create на build, в результате многие тесты стали фейлиться.
В конечном счете решил пока оставить как есть, ибо потенциальный выигрыш здесь все равно небольшой.

## Результат

В ходе оптимизации получилось сократить время прохождения тестов с 5 минут 25 секунд до 1 минуты 50 секунд.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Very very nice! Немного потюнили и в 3 раза ускорили.
Если не используете параллелизм, то за счёт него можно ещё в 2-3 раза ускорить, будет у вас test-suite в пределах одной минуты