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.

Discussion (3)

Collapse
ericovasconcelos profile image
ericovasconcelos

Good tip

Collapse
bogdaniel profile image
Bogdan Olteanu

Very nice tutorial :-)

Collapse
tomasvotruba profile image
Tomáš Votruba

Thank you!