Factory Bot1 has been getting some hardcore internal refactorings over the past few months. Traits are a great example of something that’s started very bare-bones with a few caveats and been transformed to one of my favorite features of the Factory Bot syntax. It required a pretty decent chunk of refactoring and there were bugs for quite a while due to the way attributes in general were handled.
The Old Way
Internally, Factory Bot has four different types of attributes (Dynamic,
Static, Association, and Sequence); when compiling attributes, we were sorting
attributes by the order attributes were added, moving all static attributes to
the beginning of the list (with a priority
attribute). This worked for 99% of
all cases but did have bugs (the most recent involved traits and dynamic
attributes). I wanted to
resolve this once and for all.
The New Way
Factory Bot now creates a new class per factory (with some awesome usage of
Class.new
) and
defines methods on that class for each attribute declared in the factory files.
This means Factory Bot doesn’t have to worry about sorting attributes anymore;
every attribute is effectively lazily-evaluated so it’ll return the correct
value every time. Factory Bot also uses inheritance for these anonymous
classes, resulting in a pretty significant speedup of factory interaction
(namely because we were copying all parent attributes and callbacks to each
child to mimic inheritance before).
What Does It Mean
Factory Bot is now faster!
Here’s some benchmarks from Factory Bot 2.3.0:
user system total real
build x10000 4.920000 0.010000 4.930000 ( 5.028088)
trait build x10000 6.180000 0.010000 6.190000 ( 6.296030)
inline trait build x10000 5.870000 0.010000 5.880000 ( 5.989512)
deep build x10000 8.100000 0.020000 8.120000 ( 8.285039)
attributes_for x10000 3.200000 0.010000 3.210000 ( 3.289043)
create x500 1.010000 0.320000 1.330000 ( 4.186271)
And from Factory Bot 2.4.0:
user system total real
build x10000 3.050000 0.000000 3.050000 ( 3.121359)
trait build x10000 3.260000 0.010000 3.270000 ( 3.353590)
inline trait build x10000 6.700000 0.040000 6.740000 ( 7.037460)
deep build x10000 3.400000 0.010000 3.410000 ( 3.503984)
attributes_for x10000 0.820000 0.010000 0.830000 ( 0.886641)
create x500 0.710000 0.310000 1.020000 ( 3.980102)
Grab a copy of Factory Bot 2.4.0 and speed up your suite!
Project name history can be found here.
-
Looking for FactoryGirl? The library was renamed in 2017. ↩