Weave Code
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

Test Fixtures Bundle Laravel Package

liip/test-fixtures-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev liip/test-fixtures-bundle
    

    Add the bundle to config/bundles.php (Symfony 5.1+):

    Liip\TestFixturesBundle\LiipTestFixturesBundle::class => ['test' => true],
    
  2. First Use Case: Extend Liip\TestFixturesBundle\Test\FixturesTrait in your test class:

    use Liip\TestFixturesBundle\Test\FixturesTrait;
    use Liip\TestFixturesBundle\Services\Database\DatabaseTestCase;
    
    class MyTest extends DatabaseTestCase
    {
        use FixturesTrait;
    
        protected function getDatabaseName(): string
        {
            return 'default'; // or your custom connection name
        }
    
        public function testSomething()
        {
            $this->loadFixtures([MyUserFixture::class]);
            // Test logic here
        }
    }
    
  3. Key Files to Review:

    • doc/database.md (core usage)
    • config/packages/test/liip_test_fixtures.yaml (default config)
    • src/Services/FixtureLoader.php (understanding fixture loading)

Implementation Patterns

Core Workflow

  1. Fixture Organization: Group fixtures by feature/module (e.g., UserFixtures, ProductFixtures). Use namespaces to logically separate concerns:

    // src/DataFixtures/UserFixtures.php
    namespace App\DataFixtures;
    class UserFixtures extends FixtureGroup
    {
        public function load(ObjectManager $manager)
        {
            $this->addFixture(new UserFixture());
            $this->addFixture(new RoleFixture());
        }
    }
    
  2. Test Structure:

    class UserTest extends DatabaseTestCase
    {
        use FixturesTrait;
    
        protected function setUp(): void
        {
            $this->loadFixtures([
                UserFixtures::class,
                ProductFixtures::class // Shared fixtures
            ]);
            parent::setUp();
        }
    
        public function testUserCreation()
        {
            // Test logic
        }
    }
    
  3. Database Isolation:

    • Use getDatabaseName() to target specific connections.
    • Leverage getDatabaseConfig() for custom configurations:
      protected function getDatabaseConfig(): array
      {
          return [
              'memory' => true, // In-memory DB for speed
              'purge' => true,  // Auto-purge between tests
          ];
      }
      
  4. Partial Loading: Load only specific fixtures per test method:

    public function testAdminFeatures()
    {
        $this->loadFixtures([AdminUserFixture::class]);
        // Test admin-specific logic
    }
    

Integration Tips

  • Symfony Events: Listen to liip_test_fixtures.load.fixtures to modify fixtures dynamically:

    public static function getSubscribedEvents()
    {
        return [
            'liip_test_fixtures.load.fixtures' => 'onLoadFixtures',
        ];
    }
    
    public function onLoadFixtures(LoadFixturesEvent $event)
    {
        $event->addFixture(new DynamicFixture());
    }
    
  • Custom Fixture Classes: Extend Liip\TestFixturesBundle\Services\FixtureLoader for custom loading logic:

    class CustomLoader extends FixtureLoader
    {
        protected function loadFixtures(array $fixtures): void
        {
            // Custom logic
            parent::loadFixtures($fixtures);
        }
    }
    
  • Performance:

    • Use memory: true in config for fast in-memory tests.
    • Cache fixtures with cache: true (requires doctrine/doctrine-cache-bundle).

Gotchas and Tips

Common Pitfalls

  1. Fixture Dependencies:

    • Ensure fixtures are loaded in the correct order (use orderBy in FixtureGroup):
      $this->addFixture(new RoleFixture())->orderBy(10);
      $this->addFixture(new UserFixture())->orderBy(20);
      
    • Error: ForeignKeyConstraintViolationException if dependencies are misordered.
  2. Database State:

    • Gotcha: Fixtures persist across test methods unless purge: true is set.
    • Fix: Use purgeDatabase() between tests:
      public function testA()
      {
          $this->loadFixtures([...]);
          // ...
      }
      
      public function testB()
      {
          $this->purgeDatabase(); // Reset state
          $this->loadFixtures([...]);
      }
      
  3. Configuration Overrides:

    • Gotcha: Bundle config in config/packages/test/liip_test_fixtures.yaml may be overridden by environment variables.
    • Tip: Use %env(resolve: DATABASE_URL)% for dynamic configs.
  4. Doctrine Events:

    • Gotcha: Fixtures may trigger Doctrine lifecycle events (e.g., prePersist). Disable with:
      # config/packages/test/doctrine.yaml
      doctrine:
          orm:
              event_listeners:
                  # Disable default listeners
      

Debugging Tips

  1. Fixture Loading Logs: Enable verbose logging in config/packages/test/liip_test_fixtures.yaml:

    liip_test_fixtures:
        debug: true
    
  2. Database Dumps: Use getDatabaseConnection()->getSchemaManager()->createSchemaSql() to inspect schema:

    public function testSchema()
    {
        $sql = $this->getDatabaseConnection()->getSchemaManager()->createSchemaSql(
            $this->getDatabaseConnection()->getSchemaManager()->createSchema()
        );
        file_put_contents('schema.sql', $sql);
    }
    
  3. Fixture Validation:

    • Tip: Use assertDatabaseHas() from database-testing trait:
      $this->assertDatabaseHas('users', ['email' => 'test@example.com']);
      

Extension Points

  1. Custom Fixture Types: Extend Liip\TestFixturesBundle\Services\FixtureInterface for non-Doctrine fixtures (e.g., Elasticsearch):

    class ElasticFixture implements FixtureInterface
    {
        public function load(ObjectManager $manager): void
        {
            // Custom logic
        }
    }
    
  2. Hooks: Override onPreLoadFixtures() and onPostLoadFixtures() in your test class:

    protected function onPreLoadFixtures(): void
    {
        // Pre-load logic (e.g., seed config)
    }
    
    protected function onPostLoadFixtures(): void
    {
        // Post-load logic (e.g., refresh cache)
    }
    
  3. Parallel Testing:

    • Tip: Use getDatabaseName() to generate unique DB names for parallel runs:
      protected function getDatabaseName(): string
      {
          return 'test_' . $this->getTestClassName();
      }
      

Configuration Quirks

  1. Memory vs. SQLite:

    • memory: true uses SQLite in-memory (fast but no persistence).
    • sqlite_memory: true (alternative) may behave differently in some PHP versions.
  2. Purger Strategies:

    • purge: true drops and recreates the schema.
    • For partial purges, use Liip\TestFixturesBundle\Services\Database\Purger\Purger directly:
      $this->purgeDatabase(['users', 'roles']); // Purge specific tables
      
  3. Environment Variables:

    • Gotcha: DATABASE_URL in .env.test overrides bundle config.
    • Tip: Use LIIP_TEST_FIXTURES_PURGE to toggle purging via env:
      purge: '%env(bool:LIIP_TEST_FIXTURES_PURGE,true)%'
      
  4. Doctrine Migrations:

    • Tip: Run migrations before fixtures in setUp():
      protected function setUp(): void
      {
          $this->runMigrations();
          $this->loadFixtures([...]);
      }
      
    • Requires doctrine/doctrine-migrations-bundle and:
      liip_test_fixtures:
          run_migrations: true
      
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor