2

I'm writing some functional tests for an API in Symfony that depend on having data in the database. It seems the generally accepted method for doing this is to use Fixtures and load the fixtures before testing.

It seems pretty daunting and impractical to create a robust library of Fixture classes that are suitable for all my tests. I am using the LiipFunctionalTestBundle so I only load the Fixtures I need, but it only makes things slightly easier.

For instance, for some tests I may need 1 user to exist in the database, and other tests I may need 3. Beyond that, I may need each of those users to have slightly different properties, but it all depends on the test.

I'd really like to just create the data I need for each test on-demand as I need it. I don't want to pollute the database with any data I don't need which may be a side effect of using Fixtures.

My solution is to use the container to get access to Doctrine and set up my objects in each test before running assertions.

Is this a terrible decision for any reason which I cannot foresee? This seems like a pretty big problem and is making writing tests a pain.

Another possibility it to try and use this port of Factory Girl for PHP, but it doesn't seem to have a large following, even though Factory Girl is used so widely in the Ruby community to solve this same problem.

Brian
  • 7,204
  • 12
  • 51
  • 84
  • Nothing wrong with your approach. Go with what works for you. If down the line you start to run into some of the issues that @AlpineCoder has pointed out then it's easy enough to change over. – Cerad Feb 24 '15 at 17:02
  • Hi @Brian have you already see [this](http://stackoverflow.com/questions/28584393/independent-functional-tests-with-liipfunctionaltestbundle-and-fixtures/28585103#28585103)? What you think about? – Matteo Feb 25 '15 at 06:42
  • @Matteo I'm not a big fan of that approach. There's a lot of overhead associated with creating all those classes. I'd really like finer grain control of the properties of my Entities for each specific test case. – Brian Feb 25 '15 at 13:42

1 Answers1

3

The biggest reason to fixture test data in a single place (rather than in each test as needed) is that it allows you to isolate test failures from BC-breaking schema changes to only tests that are affected by the changes directly.

A simple example:

Suppose you have a User class, in which you have a required field name, for which you provide getName() and setName(). You write your functional tests without fixtures (each test creating Users as needed) and all is well.

Sometime down the road, you decide you actually need firstname and lastname fields instead of just name. Naturally you change the schema and replace getName/setName with new get and set methods for these, and go ahead and run your tests. Test fail all over the place (anything that sets up a User), since even tests that don't use the name field have called setName() during the setup, and now they need to be changed.

Compare to using a fixture, where the User classes needed for testing are all created in one fixture. After making your breaking change, you update the fixture (in one place / class) to setup the Users properly, and run your tests again. Now the only failures you get should be directly related to the change (ie tests that use getName() for something, and every other test that doesn't care about the name field proceeds as normal.

For this reason it's highly preferred to use fixtures for complicated functional tests where possible, but if your particular schema / testing needs make it really inconvenient you can set entities up manually in tests, but I'd do my best to avoid doing so except where you really need to.

AlpineCoder
  • 627
  • 4
  • 8