Skip to content

FactoryProf

FactoryProf помогает вам анализировать использование фабрик в тестах: как часто и каким образом создаются те или иные объекты. Это помогает находить каскады фабрик — одну из самых главных причин медленных тестов.

Подробнее о каскадах фабрик читайте в статье TestProf II: Factory therapy for your Ruby tests.

Пример отчёта FactoryProf:

sh
[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:

sh
FPROF=1 rspec

# или
FPROF=1 bundle exec rake test

Режим задиры Нейта

Чтобы вы не забывали о том, сколько времени съедают ваши фабрики, мы предлагаем вам использовать специальный режим работы Factory Prof, придуманный Нейтом Беркопеком.

Добавьте в ваш rails_helper.rb или test_helper.rb следующую строчку:

ruby
require "test_prof/factory_prof/nate_heckler"

Теперь в конце каждого запуска тестов вы будете видеть, сколько времени вы потратили на создание данных фабриками:

sh
[TEST PROF INFO] Time spent in factories: 04:31.222 (54% of total time)

Флеймграфы для фабрик

Наиболее полезным форматом отчёта FactoryProf является так называемый FactoryFlame отчёт. Данный формат является адаптацией оригинальной идеи флеймграфов, представленной Брэндоном Греггом. Данный формат помогает находить каскады фабрик.

Для генерации FactoryFlame отчёте укажите flamegraph в качестве значение переменной FPROF:

sh
FPROF=flamegraph rspec

# или
FPROF=flamegraph bundle exec rake test

В результате вы получите ссылку на HTML-файл с интерактивным графиком:

FactoryFlame

Давайте разберёмся, какую информацию мы можем из него получить?

Каждая колонка представляет собой стеб фабрик или каскад — он начинается (снизу) с имени фабрики, которая была вызвана в тестовом коде, и продолжается цепочкой вложенных вызовов метода #create.

Рассмотрим пример:

ruby
factory :comment do
  answer
  author
end

factory :answer do
  question
  author
end

factory :question do
  author
end

Допустим, мы хотим создать комментарий:

ruby
create(:comment) #=> создаёт 5 объектов

Соответствующий стек фабрик выглядит следующим образом:

ruby
[:comment, :answer, :question, :author, :author, :author]

Вернёмся к графику.

Ширина колонки соответствует популярности данного стека: чем шире, тем чаще он встречается.

Ячейка root показывает общее число вызовов метода #create.

Для оптимизации времени выполнения тестов вам нужно стремиться избавиться от одновременно широких и высоких стеков на графике.