ExMachina is a library that makes creating test data in Elixir both easy and powerful. Since ExMachina’s first announcement in November 2015 we, and a large number of contributors, have been hard at work making ExMachina more flexible, more useful and more stable than ever. Today we’re announcing the public release of ExMachina 1.0.
ExMachina’s CHANGELOG has a quick rundown of what’s changed.
New factory definition syntax
The most noticeable change is the factory definition syntax. Before 1.0 factories looked like this:
def factory(:user) do
# ...
end
In 1.0 they look like this:
def user_factory do
# ...
end
Why? We changed the factory definition syntax for a variety of reasons. It is easier to jump to different factories in your factory module with “jump to symbol” that is available in some editors. But more importantly, the new syntax makes it so that you can put functions related to a factory near the factory they belong to.
Here’s an example from pre-1.0:
def factory(:user) do
# ... return user struct
end
def factory(:comment) do
# ... return comment struct
end
def make_admin(user) do
%{user | admin: true}
end
The make_admin/1
function cannot go underneath the user factory function
because Elixir will print a warning that the factory/1
functions are not
grouped together.
In ExMachina 1.0 we can group similar functions together more easily:
def user_factory do
# ... return user struct
end
# Now make_admin/1 is close to the factory it uses
def make_admin(user) do
%{user | admin: true}
end
def comment_factory do
# ... return comment struct
end
Uses Ecto terminology: create
-> insert
Before 1.0 the functions for working with factories were build
and create
.
This was mostly due to habit after working with ActiveRecord and FactoryBot.
Since Ecto uses insert
instead of create
when talking about saving to the
database, we decided to use insert
in ExMachina as well.
It’s also worth noting that Ecto is not required when using ExMachina, but if you use it, Ecto version 2.0 or higher is required now.
Introducing ExMachina.Strategy
Previously ExMachina had a build
function that returned the struct or map for
that factory, and it also had a create
function that performed an action with
the struct or map returned from build
. When using ExMachina with Ecto,
create
inserted the struct into the database.
Now instead of including build
and create
, ExMachina only includes build
by default. To perform an action with the map or struct returned from a factory
(like inserting it in the database, or encoding it as JSON) you would implement
an ExMachina.Strategy
.
This makes ExMachina very flexible because you can have multiple strategies and
can easily extract strategies to share with others as hex packages. For example
you could have a strategy for encoding as JSON, and another strategy for
encoding as XML.
Don’t worry, ExMachina comes with an
ExMachina.EctoStrategy
for inserting factories to the database. This module is used automatically when
you use ExMachina.Ecto
in your factory module.
Getting started with ExMachina 1.0
Check out the README for more info about ExMachina.
Upgrading to ExMachina 1.0
We strived to make upgrading to 1.0 as simple as possible. In mix.exs
change
your ExMachina version to {:ex_machina, "~> 1.0"}
, then run your test suite
with mix test
. ExMachina will raise errors that tell you how to upgrade to
1.0. Most of the time you can run a couple find-and-replaces and you’re ready to
go!
See the CHANGELOG for more details about what’s changed and been added in 1.0.