Symfony8 min

Faker en Symfony : generer des donnees de test realistes

Par Pierre-Arthur Demengel
SymfonyFakerTestingFixtures

Des donnees de test realistes sont essentielles pour le developpement et le testing. Des noms generiques comme "Test User" ou "Lorem Ipsum" ne revelent pas les bugs lies aux caracteres speciaux, aux longueurs de champs ou aux formats specifiques. FakerPHP genere des donnees credibles - noms francais, adresses belges, numeros de telephone valides - qui rendent vos tests plus fiables et votre environnement de dev plus agreable. Voici comment l'utiliser efficacement dans un projet Symfony 7.2.

Installation et configuration de base

FakerPHP est le fork communautaire actif de l'ancien package Faker de Francois Zaninotto :

# Installer Faker (dependance dev uniquement)
composer require --dev fakerphp/faker

Utilisation basique :

<?php
use Faker\Factory;

// Instance par defaut (anglais)
$faker = Factory::create();

// Instance francaise
$faker = Factory::create('fr_FR');

// Instance belge francophone
$faker = Factory::create('fr_BE');

echo $faker->name();          // "Jean-Pierre Dupont"
echo $faker->address();       // "42 rue de la Paix, 75001 Paris"
echo $faker->phoneNumber();   // "+33 1 23 45 67 89"
echo $faker->email();         // "jean.dupont@example.com"
echo $faker->company();       // "Martin et Fils SARL"

Providers courants

Faker organise ses generateurs en providers thematiques. Voici les plus utiles :

Identite

$faker = Factory::create('fr_FR');

$faker->firstName();           // "Marie"
$faker->lastName();            // "Lefevre"
$faker->name();                // "Marie Lefevre"
$faker->title();               // "Mme"
$faker->userName();            // "marie.lefevre"

Adresses

$faker->streetAddress();       // "12 boulevard Voltaire"
$faker->city();                // "Lyon"
$faker->postcode();            // "69001"
$faker->country();             // "France"
$faker->latitude();            // 48.8566
$faker->longitude();           // 2.3522

Contact

$faker->email();               // "marie.lefevre@example.org"
$faker->safeEmail();           // "marie@example.net" (jamais un vrai domaine)
$faker->phoneNumber();         // "01 23 45 67 89"
$faker->url();                 // "https://www.example.com"

Texte

$faker->sentence();            // "Voluptatem quia est quo consequatur."
$faker->paragraph();           // Un paragraphe de Lorem Ipsum
$faker->text(200);             // Texte de ~200 caracteres
$faker->realText(300);         // Texte realiste (extrait de livres)

Dates et heures

$faker->dateTime();                    // DateTime random
$faker->dateTimeBetween('-1 year');     // Dans la derniere annee
$faker->dateTimeThisYear();            // Cette annee
$faker->date('Y-m-d');                 // "2026-03-15"
$faker->time('H:i');                   // "14:30"

Entreprise et commerce

$faker->company();             // "Petit et Associes"
$faker->companySuffix();       // "SARL"
$faker->siret();               // "362 521 879 00034" (fr_FR)
$faker->siren();               // "362 521 879" (fr_FR)
$faker->vat();                 // "FR12362521879" (fr_FR)
$faker->catchPhrase();         // "La qualite a votre service"

Donnees techniques

$faker->uuid();                // "550e8400-e29b-41d4-a716-446655440000"
$faker->ipv4();                // "192.168.1.42"
$faker->macAddress();          // "A1:B2:C3:D4:E5:F6"
$faker->userAgent();           // "Mozilla/5.0 ..."
$faker->sha256();              // Hash SHA-256 aleatoire
$faker->boolean(70);           // true avec 70% de probabilite
$faker->randomFloat(2, 0, 100); // 42.37

Integration avec DoctrineFixturesBundle

L'usage le plus courant de Faker en Symfony est la generation de fixtures Doctrine. Combinee avec le DoctrineFixturesBundle, la creation de jeux de donnees devient triviale :

<?php
// src/DataFixtures/AppFixtures.php
namespace App\DataFixtures;

use App\Entity\User;
use App\Entity\Article;
use App\Entity\Category;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Faker\Factory;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;

class AppFixtures extends Fixture
{
    public function __construct(
        private readonly UserPasswordHasherInterface $hasher,
    ) {}

    public function load(ObjectManager $manager): void
    {
        $faker = Factory::create('fr_FR');
        $faker->seed(2026); // Donnees reproductibles

        // Creer des categories
        $categories = [];
        foreach (['Technologie', 'Science', 'Culture', 'Sport', 'Economie'] as $name) {
            $category = new Category();
            $category->setName($name);
            $category->setSlug(strtolower($name));
            $manager->persist($category);
            $categories[] = $category;
        }

        // Creer des utilisateurs
        $users = [];
        for ($i = 0; $i < 20; $i++) {
            $user = new User();
            $user->setEmail($faker->unique()->safeEmail());
            $user->setFirstName($faker->firstName());
            $user->setLastName($faker->lastName());
            $user->setPassword($this->hasher->hashPassword($user, 'password'));
            $user->setRoles($i === 0 ? ['ROLE_ADMIN'] : ['ROLE_USER']);
            $user->setCreatedAt($faker->dateTimeBetween('-2 years'));
            $manager->persist($user);
            $users[] = $user;
        }

        // Creer des articles
        for ($i = 0; $i < 50; $i++) {
            $article = new Article();
            $article->setTitle($faker->sentence(6));
            $article->setContent($faker->paragraphs(5, true));
            $article->setExcerpt($faker->text(150));
            $article->setAuthor($faker->randomElement($users));
            $article->setCategory($faker->randomElement($categories));
            $article->setPublished($faker->boolean(80));
            $article->setCreatedAt($faker->dateTimeBetween('-1 year'));
            $article->setViews($faker->numberBetween(0, 5000));
            $manager->persist($article);
        }

        $manager->flush();
    }
}

Pour un guide detaille sur les fixtures, consultez notre article sur les fixtures Symfony avec Doctrine.

Seeding : donnees reproductibles

Le seeding est crucial pour les tests automatises. Avec un seed fixe, Faker genere toujours les memes donnees :

$faker = Factory::create('fr_FR');
$faker->seed(42);

// Ces valeurs seront TOUJOURS les memes
$name1 = $faker->name();  // Toujours le meme nom
$name2 = $faker->name();  // Toujours le meme second nom

// Utile dans les tests
class UserServiceTest extends TestCase
{
    private \Faker\Generator $faker;

    protected function setUp(): void
    {
        $this->faker = Factory::create('fr_FR');
        $this->faker->seed(123);
    }

    public function testCreateUser(): void
    {
        $name = $this->faker->name();
        $email = $this->faker->safeEmail();

        // On peut ecrire des assertions sur les valeurs exactes
        // car elles sont deterministes avec le seed 123
        $user = $this->userService->create($name, $email);
        $this->assertSame($name, $user->getName());
    }
}

Custom providers : donnees metier

Pour generer des donnees specifiques a votre domaine, creez un provider personnalise :

<?php
// src/DataFixtures/Provider/EcommerceProvider.php
namespace App\DataFixtures\Provider;

use Faker\Provider\Base;

class EcommerceProvider extends Base
{
    private const PRODUCT_NAMES = [
        'Casque audio sans fil',
        'Clavier mecanique RGB',
        'Souris ergonomique',
        'Ecran 4K 27 pouces',
        'Webcam HD 1080p',
        'Hub USB-C 7 ports',
    ];

    private const PRODUCT_COLORS = [
        'Noir', 'Blanc', 'Gris sideral', 'Bleu nuit', 'Rouge vermillon',
    ];

    public function productName(): string
    {
        return static::randomElement(self::PRODUCT_NAMES);
    }

    public function productColor(): string
    {
        return static::randomElement(self::PRODUCT_COLORS);
    }

    public function productReference(): string
    {
        return strtoupper(static::lexify('???')) . '-' . static::numerify('####');
    }

    public function productPrice(): float
    {
        return round(static::randomFloat(2, 9.99, 999.99), 2);
    }

    public function ean13(): string
    {
        return static::numerify('#############');
    }
}

// Utilisation
$faker = Factory::create('fr_FR');
$faker->addProvider(new EcommerceProvider($faker));

echo $faker->productName();       // "Clavier mecanique RGB"
echo $faker->productReference();  // "KZP-4821"
echo $faker->productPrice();      // 149.99

Foundry : l'alternative moderne

Foundry (zenstruck/foundry) est l'approche moderne pour les fixtures Symfony. Il utilise Faker en interne mais ajoute un pattern factory avec des states et une API fluide :

# Installation
composer require --dev zenstruck/foundry
<?php
// src/Factory/UserFactory.php
namespace App\Factory;

use App\Entity\User;
use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;

/**
 * @extends PersistentProxyObjectFactory<User>
 */
class UserFactory extends PersistentProxyObjectFactory
{
    public static function class(): string
    {
        return User::class;
    }

    protected function defaults(): array|callable
    {
        return [
            'email' => self::faker()->unique()->safeEmail(),
            'firstName' => self::faker()->firstName(),
            'lastName' => self::faker()->lastName(),
            'password' => 'hashed_password',
            'roles' => ['ROLE_USER'],
            'createdAt' => self::faker()->dateTimeBetween('-1 year'),
        ];
    }

    // States pour des variantes
    public function admin(): static
    {
        return $this->with(['roles' => ['ROLE_ADMIN']]);
    }

    public function verified(): static
    {
        return $this->with(['verifiedAt' => self::faker()->dateTime()]);
    }
}

// Utilisation dans les fixtures
UserFactory::createMany(20);
UserFactory::new()->admin()->create();
UserFactory::new()->verified()->admin()->create();

// Utilisation dans les tests
class UserControllerTest extends WebTestCase
{
    use ResetDatabase, Factories;

    public function testShowProfile(): void
    {
        $user = UserFactory::createOne(['firstName' => 'Marie']);

        $this->client->loginUser($user->_real());
        $this->client->request('GET', '/profile');

        $this->assertResponseIsSuccessful();
        $this->assertSelectorTextContains('h1', 'Marie');
    }
}

Foundry est desormais la methode recommandee par la communaute Symfony. Elle offre une meilleure ergonomie et des tests plus lisibles que l'utilisation directe de Faker avec les fixtures.

Bonnes pratiques

  • Utilisez toujours safeEmail() au lieu de email() pour eviter d'envoyer des emails a de vraies adresses en cas de bug
  • Seedez vos fixtures pour garantir la reproductibilite des tests
  • Definissez la locale adaptee a votre public cible (fr_FR, fr_BE)
  • Utilisez unique() pour les champs avec contrainte d'unicite : $faker->unique()->email()
  • Evitez Faker en production : installez-le en --dev uniquement

Pour gerer la structure de base de donnees associee a vos fixtures, consultez notre guide sur les migrations Doctrine. Et pour des requetes avancees sur vos donnees de test, voyez notre reference findBy et findAll.

Besoin d'aide pour mettre en place un environnement de test solide sur votre projet Symfony ? Consultez mes tarifs, explorez mes services, ou contactez-moi pour un accompagnement personnalise.

Questions fréquentes

13 projets livrésGrand-Est & BelgiqueLighthouse >90Disponible immédiatement

Un projet en tête ?

Discutons de votre site web. Réponse garantie sous 24h.

Ou appelez directement :06 95 41 30 25

WhatsApp
Appeler