One of the greatest things of testing Ruby on Rails applications was usage of Factories, managed by FactoryGirl. It changed the way the test data was managed in test. Instead of defining fixtures one by one, in a single
.yml configuration, it allowed to generate required models per test. This concept is very convenient, however it is not widespread in PHP world. Probably, this was because, there is no single ORM in PHP, like ActiveRecord is for Ruby. We have Doctrine, Eloquent, and each major framework has its own ORM layer, so that we it is pretty hard to deal with models of those frameworks in one manner.
But it looks like factories finally came to PHP! The League of Extraordinary Packages produced a great package, self-claimed as factory_girl for PHP. Meet Factory Muffin. It allows simple generation of database records for integration and functional testing. Let’s see how it can be used with Codeception.
Setup in Codeception
At first lets add
league/factory-muffin": "~2.0 to
Then we execute
As you may noticed, FactoryMuffin uses awesome Faker library for generating random data for models.
For using factories inside tests we will create
We will define factories in the
_initialize method of
Let’s say we have two models,
User in application. This is how we specify rules for generating new objects of these models.
This is how generation of Post and User is defined. From the box, Muffin is designed to work with ActiveRecord models, and with Eloquent in particular. So you can use it in Yii, Phalcon, yet we will demonstrate its usage in Laravel application. FactoryMuffin can also be customized to work with Doctrine as well.
Using Factories in Laravel
To use FactoryMuffin in Laravel functional tests we need to create additional methods in
FactoryHelper for generating and saving records:
haveUsers methods. They will populate database with number of records specified. We will need to clean up those records at the end of a test.
By including FactoryHelper to the functional suite config, we can use it inside the actor (
This allows us to test features like pagination. For instance, we can check that only 20 posts are listed on a page:
Factories in Unit Tests
Factories can also be used in unit testing. Let’s say user can create posts, and in order to optimize queries we are saving number of user posts in
num_posts column of
users table. We are going to test that this column is updated each time a new post by user is created.
We will need one more method added into
After we include
FactoryHelper into unit suite we can use its methods in tests:
As you see, factories make your tests clean and expressive. Forget about managing test data manually, forget about fixtures. Use FactoryMuffin.