Generate Symfony test data with Doctrine

Maintaining a Doctrine fixture class per entity plus the factories to wire them together rots the moment the schema moves, and copying a production dump into your test suite is a GDPR problem waiting to happen. The fix: realistic, foreign-key-consistent data generated straight from your schema, data that actually looks real, not "Premium Widget 1" and lorem ipsum. One command fills the whole database.

Realistic, foreign-key-consistent Symfony test data generated from a Doctrine schema in SeedBase

Free tier, no card. Want to see the output before wiring anything up? Try the login-free sandbox: paste a schema, generate, look at the rows.

Fill your database with one command

As a DoctrineFixturesBundle alternative, you stop writing a fixture class per entity. Add the bundled fixture and load it the way you already load fixtures:

php bin/console doctrine:fixtures:load

The bundled SeedbaseFixtures class generates and loads foreign-key-consistent data over the Doctrine connection. Your schema must already exist; your migrations own it. SeedBase reads that schema, generates realistic rows that satisfy every relationship, and inserts them in the right order so the load succeeds with constraints on.

Seed the database in a test

Need data inside a single test instead of a global fixture load? Pull in the trait and seed the database directly through your Doctrine connection:

use Seedbase\Doctrine\InteractsWithSeedbase;

$this->seedFromSeedbase($connection);

Install with composer require --dev seedbase/seedbase. The InteractsWithSeedbase trait fetches a generation and loads it into the database your test talks to, so your test arranges against realistic, foreign-key-consistent rows without a hand-written fixture in sight.

Realistic, foreign-key-consistent data

The value is the engine, not the thin Symfony adapter. SeedBase resolves foreign keys across tables, so an order that points at a customer always finds a customer that exists, and the rows load with constraints on. It uses realistic distributions and coherent free text, so a description reads like a description and an email reads like an email, instead of "Premium Widget 1" or lorem ipsum your assertions can never trust.

Honest note: SeedBase was tested against a real project with 226 tables, that is where the foreign-key and edge-case handling came from. The engine is multi-database: PostgreSQL, MySQL, MariaDB, SQLite and SQL Server, so the same generation seeds whichever one your Doctrine connection points at. EU-hosted, no third-party trackers, and you can export everything, so nothing is locked in.

Deterministic and reproducible

Generation is seeded. The same seed produces the same data, every run. That keeps CI reproducible: the same fixture yields the same rows on every machine, so a green build stays green for the right reason. When a test fails, reuse the seed and you reproduce the exact dataset that broke it, instead of chasing a fixture that has since been hand-edited.

Free tier

Generation and JSON download are free to use. You do not need push-to-database or any paid feature to seed your Symfony tests, because the data loads through your own Doctrine connection. Generate once, download the JSON, and let the fixture or the trait wire it into the database. Pro adds Parquet export, direct database push and higher row limits when you want them.

Try it

There is a runnable example you can clone and run, so you watch a real FK-consistent dataset get loaded through a Doctrine connection. Then point it at your own schema.

php examples/doctrine_seed_demo.php

Stop hand-writing Doctrine fixtures.

Generate a foreign-key-consistent dataset once and seed your Symfony database with one command. Free tier, no card.

Create a free account

Frequently asked questions

Is it free?

Yes. Generation and JSON download are part of the free tier, so you can pull a foreign-key-consistent dataset and load it into your Symfony database through your own Doctrine connection at no cost. Pro adds Parquet export, direct database push and higher row limits, but you do not need any of that to seed your tests.

How is this different from writing Doctrine fixtures by hand?

You do not write a fixture class per entity anymore. SeedBase fills the database foreign-key-consistent from your schema, with realistic distributions, so an order that points at a customer actually finds that customer and the values look real instead of "Premium Widget 1" or lorem ipsum.

Does it work with DoctrineFixturesBundle?

Yes. A single SeedbaseFixtures class runs via doctrine:fixtures:load and loads the generated data through your Doctrine connection. Or use the InteractsWithSeedbase trait in a test to seed the database directly without the bundle.

Is it deterministic?

Yes, per seed. The same seed produces the same data every run, so CI is reproducible: the same fixture yields the same rows, and a failing test can be reproduced exactly by reusing the seed.