Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Data Fixtures Extension Laravel Package

vipsoft/doctrine-data-fixtures-extension

Doctrine Data Fixtures extension for Laravel Doctrine that brings fixture loading to Laravel. Seed your database with test or demo data via Artisan, making it easy to manage repeatable fixtures for development, testing, and staging environments.

View on GitHub
Deep Wiki
Context7

Getting Started

Requirements. This is a Behat 3 extension from the pre-Symfony 4 era (last release 2017). You need behat/behat, behat/symfony2-extension (to give Behat access to the Symfony kernel/container), doctrine/orm, and doctrine/data-fixtures. PHP 5.6–7.1 is the realistic support envelope; expect friction on PHP 7.4+/8.x.

Install (dev only).

composer require --dev vipsoft/doctrine-data-fixtures-extension doctrine/data-fixtures

Where to look first.

  1. README.md in the repo — the whole configuration surface is about 20 lines.
  2. src/Extension.php — the Configuration node defines the only three options you'll touch: lifetime, autoload, directories.
  3. src/ServiceContainer/ (or equivalent hook/loader class) — shows how the doctrine service is pulled from the Symfony container and where the purge/load hooks are wired.

First use case — seed one entity per scenario. Create a fixture class under features/fixtures using the standard Doctrine Data Fixtures API:

namespace App\Features\Fixtures;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
use App\Entity\User;

class UserFixtures extends AbstractFixture
{
    public function load(ObjectManager $manager)
    {
        $u = new User();
        $u->setEmail('[email protected]');
        $manager->persist($u);
        $manager->flush();
    }
}

Wire it up in behat.yml:

default:
  suites:
    default:
      contexts: [App\Features\Bootstrap\FeatureContext]
  extensions:
    Behat\Symfony2Extension:
      kernel:
        env: test
        debug: true
    vipsoft\DoctrineDataFixturesExtension\Extension:
      lifetime: scenario
      autoload: true
      directories:
        - %paths.base%/features/fixtures

Run vendor/bin/behat --dry-run first to confirm the extension boots, then run one scenario. On every scenario the DB is purged and the fixture directory re-loaded, so your Mink/API steps can log in as [email protected] without any setup step of their own.

Implementation Patterns

Scenario vs. feature lifetime. lifetime: scenario is the default and the safe choice — purge + reload after each scenario. lifetime: feature loads once per feature, which is only appropriate for read-only suites; any step that writes data will leak state into the next scenario.

Fixture organization mirrors your features. Keep one directory per suite or bounded context (features/admin/fixtures, features/shop/fixtures) and list them in directories. Subdirectories are traversed, so Fixtures/ class namespaces must match Composer's PSR-4 mapping when autoload: true.

Use Data Fixtures idioms — they apply verbatim. Because the extension delegates to doctrine/data-fixtures, getOrder(), getDependencies(), and AbstractFixture::setReference all work. Ordered fixtures are the cleanest way to seed an Order that requires a User and a Product:

public function getDependencies() { return [UserFixtures::class, ProductFixtures::class]; }

Combine with the Symfony2 extension, and let the kernel do the wiring. The extension resolves your entity manager from the Symfony doctrine service, so your fixtures should use ObjectManager/EntityManagerInterface injection — do not instantiate an EM inside a fixture.

Prefer references over hard-coded IDs. If a scenario must "act as the seeded user", expose it via ReferenceRepository in your context ($this->getReference('user.behat')) instead of hard-coding a primary key.

Test-env isolation is a workflow, not a config. Always run Behat against kernel.env: test pointing at a dedicated schema/DB (e.g. app_test). The extension purges what Symfony's doctrine service is configured for — if that is your dev DB, your dev DB is gone.

Reduce purge cost on large suites. Purging via ORMPurger is slow and triggers FK constraint errors on related tables. For large schemas, either (a) split out slow features into a profile that loads fixtures once, or (b) keep the extension but wrap scenarios in transactions via dama/doctrine-test-bundle, which conflicts with purge-by-default — choose one strategy, don't mix.

Use profiles for conditional fixture loading. The extension has no per-scenario tag filter in the upstream release. If some scenarios need no data, model that with separate behat.yml profiles and directories lists rather than branching inside fixtures.

Serving the fixtures to web tests. With Mink, the browser talks to the same DB as the kernel only if your test HTTP server uses kernel.env=test. Seed the fixture, then drive the UI; seed via autoload + directories, never manually in a step definition, or you lose the automatic purge.

Gotchas and Tips

Abandoned since January 2017. No maintenance means: no Symfony 4/5/6 support, no PHP 8 support without forking, and no compatibility with doctrine/data-fixtures ≥ 1.4 API changes. Treat it as a starting point, not a dependency you can leave alone — fork it or vendor it if the project survives long.

Purging is the default and it is destructive. Misconfigured kernel.env (e.g. pointing at dev) will drop data in your development database on every Behat run. Verify the DB name in config/packages/test/doctrine.yaml (or parameters.yml in older Symfony) before your first run, not after.

autoload: false is easy to misread. It means "rely on Symfony/Doctrine discovery of classes from your directories as PSR-4 mappings", not "skip loading". If fixture classes are in the global namespace but autoload: true, Composer will not resolve them; if they're namespaced but the directory is not declared in composer.json, discovery fails. Keep namespaces and PSR-4 paths aligned.

FK constraint failures during purge. ORMPurger does not disable FK checks by default on all DB platforms. Common symptoms: SQLSTATE[23000]: Integrity constraint violation on purge of a child table. Fix by configuring the purger (cascade/exclude) or by ordering fixture deletion in your own subclassed loader.

The doctrine service must exist in the container. behat/symfony2-extension must be installed and configured, and the container must be bootable under test. If the extension "does nothing", check behat -vvv boot output — the failure usually manifests as a silent no-op rather than an error because the hook is skipped when the service isn't available.

Fixture classes are reloaded per process, but the kernel is not. Any kernel-level caching (e.g. proxy cache) persists across scenarios. If you change a fixture, restart Behat to avoid stale proxy classes — --no-interaction won't help here.

No first-class ODM/EM-multi support. The extension resolves the doctrine service which maps to the default manager. Multiple entity managers or a MongoDB ODM setup need explicit service configuration and usually a fork of the loader. Confirm the extension version you pin supports your manager before designing fixtures around it.

Debugging checklist, in order:

  1. behat --dry-run -vvv — does the extension appear in "extensions" boot output?
  2. bin/console doctrine:schema:validate --env=test — is the test DB reachable and current?
  3. Confirm %paths.base% resolves correctly; older extension versions rely on Behat's %paths.base% parameter and silently miss the directory if it's wrong.
  4. If fixtures load but tests still see stale data, check the lifetime and whether the test server and Behat share the same DB.

Extension points. The loader class is a service inside the extension's container; you can override it or decorate with a custom PurgeableFixtureLoader (e.g. to switch purger, add truncation, or skip purge for a tag). Subclass AbstractFixture for shared setReference helpers instead of duplicating boilerplate across fixture classes. The Extension::load/process methods are the natural place to inject a custom loader — but because the package is unmaintained, prefer forking over monkey-patching a vendor directory.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route