Fixtures für Testdaten
Fixtures für Testdaten
~13 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Zum Abschluss von Block 4 lösen wir ein praktisches Problem: statt bei JEDEM Datenbank-Reset manuell Testdaten über die Web-Oberfläche einzugeben, generieren wir sie REPRODUZIERBAR per Code.
Das Fixtures-Bundle installieren
composer require --dev doctrine/doctrine-fixtures-bundleEine Fixture-Klasse erstellen
php bin/console make:fixtures ProjectFixtures<?php
declare(strict_types=1);
namespace App\DataFixtures;
use App\Entity\Project;
use App\Entity\Task;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
class ProjectFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
$projekt = (new Project())
->setName('Website-Relaunch')
->setDescription('Kompletter Redesign der Firmenwebsite');
$manager->persist($projekt);
$aufgabenTitel = ['Design-Konzept erstellen', 'Backend aufsetzen', 'Texte finalisieren'];
foreach ($aufgabenTitel as $titel) {
$aufgabe = (new Task())
->setTitel($titel)
->setProject($projekt);
$manager->persist($aufgabe);
}
$manager->flush();
}
}Beachten Sie: flush() wird nur EINMAL am ENDE aufgerufen, NICHT nach jedem persist() – bei größeren Fixture-Mengen deutlich performanter, da alle Objekte in EINER Transaktion geschrieben werden.
Fixtures laden
php bin/console doctrine:fixtures:loadAchtung: doctrine:fixtures:load LEERT standardmäßig ALLE Tabellen, BEVOR es die Fixtures lädt – KEIN additiver Vorgang! NIEMALS versehentlich gegen eine Produktionsdatenbank ausführen. Mit --append lassen sich Fixtures OHNE vorheriges Leeren hinzufügen, falls das gewünscht ist.
Beziehungen zwischen mehreren Fixture-Klassen
Braucht eine Fixture-Klasse Objekte aus einer ANDEREN – z. B. Aufgaben, die einem bestimmten Nutzer zugewiesen sind – nutzt man ObjectReferences statt die Fixtures manuell in der richtigen Reihenfolge auszuführen:
<?php
declare(strict_types=1);
namespace App\DataFixtures;
use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
class UserFixtures extends Fixture
{
public const string ANNA_REFERENCE = 'user-anna';
public function load(ObjectManager $manager): void
{
$anna = (new User())->setName('Anna Schmidt');
$manager->persist($anna);
$manager->flush();
$this->addReference(self::ANNA_REFERENCE, $anna);
}
}use App\DataFixtures\UserFixtures;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
class ProjectFixtures extends Fixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager): void
{
$projekt = (new Project())->setName('Website-Relaunch');
$aufgabe = (new Task())
->setTitel('Design-Konzept erstellen')
->setProject($projekt);
// Referenz aus UserFixtures wiederverwenden:
$anna = $this->getReference(UserFixtures::ANNA_REFERENCE, User::class);
$projekt->addMitglied($anna);
$manager->persist($projekt);
$manager->persist($aufgabe);
$manager->flush();
}
public function getDependencies(): array
{
return [UserFixtures::class];
}
}DependentFixtureInterface/getDependencies() stellt sicher, dass UserFixtures IMMER VOR ProjectFixtures ausgeführt wird – unabhängig von der alphabetischen oder zufälligen Standard-Reihenfolge.
Faker: realistischere Testdaten generieren
composer require --dev fakerphp/fakeruse Faker\Factory;
$faker = Factory::create('de_DE');
for ($i = 0; $i < 20; $i++) {
$aufgabe = (new Task())
->setTitel($faker->sentence(4))
->setProject($projekt);
$manager->persist($aufgabe);
}Tipp: Faker eignet sich hervorragend für GROSSE Mengen realistisch aussehender Testdaten (z. B. für Performance-Tests in Block 8), aber für die KERN-Fixtures (wie Anna in diesem Kapitel) sind feste, benannte Werte besser – so bleibt in Tests (Block 7) NACHVOLLZIEHBAR, WELCHER konkrete Nutzer gemeint ist.
Damit ist Block 4 (Doctrine ORM & Datenbank) abgeschlossen! Unser Aufgaben-Manager hat jetzt eine vollständige, migrationsversionierte Datenbankstruktur mit reproduzierbaren Testdaten. Block 5 fügt Security hinzu – Registrierung, Login und Zugriffskontrolle, damit nur Projekt-Mitglieder ihre eigenen Projekte sehen.