Symfony2, Doctrine, FOSUserBundle and fixtures for functional testing

The scenario

An application built with Symfony2 framework which uses the Doctrine2 ORM for persistence.

The goal

To make functional tests allowing to purge and initialize the database with doctrine fixtures.

Before to start

In the project I have used the FosUserBundle, to allow better user login, registration, etc andĀ DoctrineFixturesBundle, which allow to fill a database with fixtures based on our Doctrine entities.

To load doctrine fixtures into database you need to execute the command line:

That means for each test you need to clean up the database and load the fixtures manually.

Our objective is the automate this process before executing each test.

Doctrine fixtures and the creation of FOSUserBundle users

Because we are using Doctrine fixtures we need a class that implementsĀ FixtureInterface interface (see documentation). The problem is we want to create FOSUserBundle user instances and that requires we have access to the container to get a reference to the user management service, so we need to set access to the container too. Nothing we can’t find in the documentation:

The test class

In your test class you need to define the setUp method that is responsible to prepare the database fixtures.
The setup method makes two important things, first purge the tables on the database to remove any previous changes make by previous tests and, second, initialize the database with a set of fixtures.

Note how

we need to inject a reference to the container in the fixtures class.

It is necessary to make it by hand. The dependency isn’t injected automatically because we are running a PHPUnit test, not a Symfony2 application.

1 Comments

  1. That’s one way to do it. I think it gets more complex as your database gets more complex. For instance, what if certain data are supposed to be part of the initial state of a newborn database? Then you have to know which entities to purge and which to keep.

    An alternative approach is to have a single way to build a database, whether it is being used for an automated test, to support a manual test environment, or to build/upgrade a production database. You can then use that mechanism in your test suites to ensure that you have a fresh database before each test/test suite/library of tests/whatever.

    In addition to supplying the stability you want for your tests, it also ensures that the way a database is built/upgraded is exercises and validated by your automated and manual tests. Then, if I want to run more than one test against a database instance, I tend to try to write the tests so they don’t step on each other by eradicating coupling to data that are accessed by one test and modified or created by another.

    It’s another way of doing things that does cost a little more to start but it might be worth considering.

    Reply

Leave a Comment.