FactoryProf
FactoryProf помогает вам анализировать использование фабрик в тестах: как часто и каким образом создаются те или иные объекты. Это помогает находить каскады фабрик — одну из самых главных причин медленных тестов.
Подробнее о каскадах фабрик читайте в статье TestProf II: Factory therapy for your Ruby tests.
Пример отчёта FactoryProf:
[TEST PROF INFO] Factories usage
Total: 15285
Total top-level: 10286
Total time: 299.5937s
Total uniq factories: 119
total top-level total time time per call top-level time name
6091 2715 115.7671s 0.0426s 50.2517s user
2142 2098 93.3152s 0.0444s 92.1915s post
...В данном отчёте отображается как общее число использования фабрики, так и отдельно число верхнеуровневых вызовов, т.е. без учёта вызовов внутри других фабрик (например, при создании ассоциированных объектов).
NOTE: FactoryProf учитывает только объекты, сохраняемые в базе данных, то есть объекты, созданные с помощью метода #create FactoryGirl/FactoryBot или Fabrication.
Инструкция
FactoryProf работает как с FactoryGirl/FactoryBot, так и с Fabrication.
Для запуска профилирования используйте переменную окружения FPROF:
FPROF=1 rspec
# или
FPROF=1 bundle exec rake testРежим задиры Нейта
Чтобы вы не забывали о том, сколько времени съедают ваши фабрики, мы предлагаем вам использовать специальный режим работы Factory Prof, придуманный Нейтом Беркопеком.
Добавьте в ваш rails_helper.rb или test_helper.rb следующую строчку:
require "test_prof/factory_prof/nate_heckler"Теперь в конце каждого запуска тестов вы будете видеть, сколько времени вы потратили на создание данных фабриками:
[TEST PROF INFO] Time spent in factories: 04:31.222 (54% of total time)Флеймграфы для фабрик
Наиболее полезным форматом отчёта FactoryProf является так называемый FactoryFlame отчёт. Данный формат является адаптацией оригинальной идеи флеймграфов, представленной Брэндоном Греггом. Данный формат помогает находить каскады фабрик.
Для генерации FactoryFlame отчёте укажите flamegraph в качестве значение переменной FPROF:
FPROF=flamegraph rspec
# или
FPROF=flamegraph bundle exec rake testВ результате вы получите ссылку на HTML-файл с интерактивным графиком:

Давайте разберёмся, какую информацию мы можем из него получить?
Каждая колонка представляет собой стеб фабрик или каскад — он начинается (снизу) с имени фабрики, которая была вызвана в тестовом коде, и продолжается цепочкой вложенных вызовов метода #create.
Рассмотрим пример:
factory :comment do
answer
author
end
factory :answer do
question
author
end
factory :question do
author
endДопустим, мы хотим создать комментарий:
create(:comment) #=> создаёт 5 объектовСоответствующий стек фабрик выглядит следующим образом:
[:comment, :answer, :question, :author, :author, :author]Вернёмся к графику.
Ширина колонки соответствует популярности данного стека: чем шире, тем чаще он встречается.
Ячейка root показывает общее число вызовов метода #create.
Для оптимизации времени выполнения тестов вам нужно стремиться избавиться от одновременно широких и высоких стеков на графике.