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 Test Bundle Laravel Package

dama/doctrine-test-bundle

A Symfony bundle that speeds up Doctrine tests by wrapping DBAL connections in a static driver and rolling back a transaction after each test, keeping tests isolated without schema rebuilds or fixture reloads. It also configures a PSR-6 static array cache.

View on GitHub
Deep Wiki
Context7

Getting Started

Scope note: dama/doctrine-test-bundle is a Symfony/Doctrine bundle, not a Laravel package. In a Laravel app, use Laravel’s RefreshDatabase / DatabaseTransactions unless you are specifically running Doctrine/Symfony test infrastructure.

Minimal Setup

  1. Installation:

    composer require --dev dama/doctrine-test-bundle
    
  2. Enable the Bundle (in config/bundles.php):

    DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
    
  3. Configure PHPUnit (phpunit.xml):

    <extensions>
        <bootstrap class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension" />
    </extensions>
    
  4. Verify DBAL Configuration (if using DBAL < 4):

    # config/packages/doctrine.yaml
    doctrine:
        dbal:
            connections:
                default:
                    use_savepoints: true
    

First Use Case

Run a test that interacts with Doctrine (e.g., WebTestCase or KernelTestCase). The bundle will:

  • Auto-start a transaction before each test.
  • Roll back changes after each test (unless skipped).
  • Cache metadata and queries in-memory for speed.

Example:

// src/Tests/Entity/UserTest.php
public function testUserCreation(): void
{
    $user = new User();
    $user->setName('Test User');

    $entityManager = self::getContainer()->get('doctrine')->getManager();
    $entityManager->persist($user);
    $entityManager->flush();

    $this->assertEquals(1, $entityManager->getRepository(User::class)->count([]));
    // Changes rolled back automatically after test
}

Implementation Patterns

Workflows

  1. Transactional Tests:

    • Use #[SkipDatabaseRollback] to exclude specific tests/classes from rollback:
      #[SkipDatabaseRollback]
      public function testDebugState(): void
      {
          // Changes persist after test
      }
      
  2. Debugging Failed Tests:

    • Temporarily commit changes to inspect state:
      public function testDebugState(): void
      {
          // ... test logic
          \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver::commit();
          die; // Inspect DB state
      }
      
    • In v8.7.0+, avoid leaving transactions open when using manual debugging paths; the bundle will warn about transactions that were never closed.
  3. Custom Connection Keys (for read/write replicas):

    dama_doctrine_test:
        connection_keys:
            default:
                primary: primary_key
                replicas:
                    replica_one: replica_key
    
  4. Disabling Features:

    dama_doctrine_test:
        enable_static_connection: false
        enable_static_query_cache: false
    

Integration Tips

  • Fixtures: Use doctrine/doctrine-fixtures-bundle with load() in setUp() (changes rolled back automatically).
  • Behat: Behat 4 is supported as of v8.7.0. Enable the extension in behat.yml:
    extensions:
        DAMA\DoctrineTestBundle\Behat\ServiceContainer\DoctrineExtension: ~
    
  • Performance: Disable caching for slow tests:
    dama_doctrine_test:
        enable_static_meta_data_cache: false
    

Gotchas and Tips

Pitfalls

  1. Implicit Transactions:

    • Queries like ALTER TABLE, DROP TABLE, or CREATE INDEX may commit transactions implicitly. Error:
      PDOException: SAVEPOINT DOCTRINE2_SAVEPOINT_X does not exist
      
    • Fix: Avoid DDL in tests or use #[SkipDatabaseRollback].
  2. Replica Inconsistencies:

    • By default, primary/replica connections share the same driver. Override with connection_keys if needed:
      dama_doctrine_test:
          connection_keys:
              default:
                  primary: primary_key
                  replicas:
                      replica_one: replica_key
      
  3. PHPUnit Version:

    • Supports PHPUnit 11/12/13. v8.7.0 explicitly allows PHPUnit 13 as a dev dependency. Use SYMFONY_PHPUNIT_VERSION to enforce version:
      SYMFONY_PHPUNIT_VERSION=13 php bin/phpunit
      
  4. Unclosed Transactions:

    • v8.7.0 adds warnings for transactions that were never closed. This usually means manual beginTransaction() / commit() / rollBack() calls are unbalanced, or a debugging die/exit path skipped cleanup.
    • Fix: Pair manual transaction calls, avoid leaving open transactions in setUp()/tearDown(), and use #[SkipDatabaseRollback] only for intentional persisted state.

Debugging

  • Transaction State: Check active savepoints with:

    $connection = $entityManager->getConnection();
    $connection->getWrappedConnection()->getTransactionNestingLevel();
    
  • Cache Issues: Clear static caches manually if tests behave unexpectedly:

    \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver::clearStaticConnections();
    
  • Unclosed Transaction Warnings: If v8.7.0 reports an open transaction, audit manual transaction handling, DDL statements, and early-exit debugging code. Ensure the transaction is committed or rolled back before the test ends.

Extension Points

  1. Custom Middleware: Register middleware with higher priority:

    # config/services.yaml
    services:
        App\Doctrine\TestMiddleware:
            tags: [doctrine.middleware]
    
  2. Override StaticDriver: Extend StaticDriver to customize behavior (e.g., logging):

    class CustomStaticDriver extends \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver
    {
        public function beginTransaction(): void
        {
            \Log::info('Transaction started');
            parent::beginTransaction();
        }
    }
    

    Register it in config/packages/doctrine_test.yaml:

    dama_doctrine_test:
        static_driver_class: App\Doctrine\CustomStaticDriver
    

Tips

  • Test Speed: Enable all static features for maximum performance:
    dama_doctrine_test:
        enable_static_connection: true
        enable_static_meta_data_cache: true
        enable_static_query_cache: true
    
  • Large Datasets: Disable caching if memory usage is high:
    dama_doctrine_test:
        enable_static_query_cache: false
    
  • CI/CD: Use #[SkipDatabaseRollback] for integration tests that require persisted state.
  • Behat 4: If upgrading Behat, v8.7.0 adds Behat 4 support; keep the same Doctrine extension registration in behat.yml.
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log