DEV Community

Cover image for Move Fixtures Out of src/ Folder
Renan
Renan

Posted on

Move Fixtures Out of src/ Folder

We'll see in this post an alternative place to write fixtures in an Symfony application.


According to the Symfony Framework Best Practices, fixtures should be placed in src/DataFixtures/.

I'll briefly argue against this.


Development, tests, and build stuff is supposed to be discarded once the application is built. Fixtures are precisely this, a set of files for testing and/or development purposes.

I would say we should place fixtures outside of src/ for the same reasons we write tests in the tests/ directory. It's better to not bloat the src/ with code that isn't business logic.

The golden rule is to not pollute src/ directory with non-runtime stuff.


Fixtures Under fixtures/

I propose to place fixtures inside the fixtures/ directory in the root of the project instead of src/DataFixtures/.

From:

project/
└─ src/
   └─ DataFixtures/

To:

project/
├─ fixtures/
└─ src/

Implementation

Let's make it real in your Symfony application. It may work with Symfony Demo as well.

Move Files

  1. Move the src/DataFixtures/ directory to the root;
  2. Rename it as fixtures/; and
  3. Change its classes namespaces to App\Fixtures*.

At this point, the doctrine:fixtures:load command doesn't work because it can't find fixtures anymore. If you try running it you'll get this error message:

[ERROR] Could not find any fixture services to load.

In order to fix it, we must:

  • Inform Composer there is a new directory that contains classes (dev only); and
  • Make the classes inside this directory loadable as service (dev only as well).

Fix Classes Autoloading

Add "App\\Fixtures\\": "fixtures/"* to the autoload-dev section in composer.json.

     "autoload-dev": {
         "psr-4": {
+            "App\\Fixtures\\": "fixtures/",
             "App\\Tests\\": "tests/"
         }
     },

Don't forget to run:

composer dump-autoload

Configure Services Loading

Make the new fixtures/ content* findable by loading them automaticaly in config/services_dev.yaml.

# config/services_dev.yaml

services:
    _defaults:
        autowire: true
        autoconfigure: true

    App\Fixtures\:
        resource: '../fixtures/*'

If you need fixtures in another mode (e.g. test), create the corresponding file (e.g. config/services_test.yaml) with the same content above.

Fin

The command below should work as before.

bin/console doctrine:fixtures:load

* I use App\Fixtures instead of App\DataFixtures as namespace. It's up to you to adopt it or not.

Latest comments (3)

Collapse
 
bogdaniel profile image
Bogdan Olteanu

Very nice tutorial :-)

Collapse
 
tomasvotruba profile image
Tomáš Votruba

Thank you!

Collapse
 
ericovasconcelos profile image
ericovasconcelos

Good tip