Doctrine Test Bundle

repository·master·Indexed 22 days ago

https://github.com/dmaicher/doctrine-test-bundle

A Symfony bundle that makes test suites more efficient and isolated by using transactions to roll back database changes after every test. It optimizes Doctrine caching and provides integration for PHPUnit and Behat, including the #[SkipDatabaseRollback] attribute for specific tests and a StaticDriver for managing driver connection reuse via connection keys.

Tokens
3.5K
Snippets
15
Records
16
Agent score
79%

What's inside dama/doctrine-test-bundle

  1. Debug database state by manually committing transactions

    master

    Because the bundle automatically rolls back all changes after a test, you cannot inspect the database state after a failure using standard tools. To debug, you can manually commit the transaction and terminate the process to persist the changes:

    public function testMyTestCaseThatINeedToDebug()
    {
        // ... database changes
        \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver::commit();
        die;
        // The changes are now persisted in the DB for inspection
    }
    \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver::commit();
    die;
  2. Configure PHPUnit to use the Doctrine Test Bundle

    master

    To enable automatic database rollbacks for every PHPUnit testcase, add the PHPUnitExtension to your phpunit.xml configuration:

    <phpunit>
        ...
        <extensions>
            <bootstrap class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension" />
        </extensions>
    </phpunit>

    Requirements & Compatibility:

    • phpunit/phpunit must be a dev dependency (versions 11, 12, and 13 are supported via the built-in extension).
    • Compatible with symfony/phpunit-bridge and its simple-phpunit script. If using the bridge, you may need to set the SYMFONY_PHPUNIT_VERSION environment variable to ensure a PHPUnit 10+ version is used.
  3. Install and set up the Doctrine Test Bundle

    master

    To use the bundle for isolated database testing in Symfony, follow these steps:

    1. Install via Composer:

      composer require --dev dama/doctrine-test-bundle
    2. Enable the Bundle: If you are not using Symfony Flex, manually add the bundle to config/bundles.php:

      return [
          //...
          DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
          //...
      ];
    3. Configure DBAL (Version 8+ and DBAL < 4 only): Ensure use_savepoints is enabled for your relevant connections in your Doctrine configuration:

      doctrine:
          dbal:
              connections:
                  default:
                      use_savepoints: true
    composer require --dev dama/doctrine-test-bundle
  4. Use the Doctrine Test Bundle with Behat

    master

    To enable automatic database rollbacks for Behat scenarios, add the DoctrineExtension to your behat.yml configuration:

    default:
       # ...
       extensions:
           DAMA\DoctrineTestBundle\Behat\ServiceContainer\DoctrineExtension: ~

    Important Limitation: This only works if the tests are executed in the same process as Behat. It will not work when using tools like Selenium that call your application in a separate process.

    default:
       extensions:
           DAMA\DoctrineTestBundle\Behat\ServiceContainer\DoctrineExtension: ~
  5. Customize driver connection reuse via connection_keys

    master

    The bundle manages driver connections statically in the current PHP process. You can control how these connections are reused by assigning connection_keys.

    Reusing the same connection

    If multiple DBAL connections are assigned the same key, they will share the same underlying internal driver connection instance.

    dama_doctrine_test:
        connection_keys:
            default: custom_key
            foo: custom_key

    Separate connections for Primary and Replicas

    Since v8.1.0, the bundle uses the same driver connection for both primary and replicas by default. To force separate connections for primary and replicas, assign different keys:

    dama_doctrine_test:
        connection_keys:
            default:
                primary: custom_key_primary
                replicas:
                    replica_one: custom_key_replica
  6. Configure bundle settings (connections, metadata, and query cache)

    master

    The bundle provides configuration keys to enable or disable its core features. By default, all features are enabled for all connections.

    Default Configuration:

    dama_doctrine_test:
        enable_static_connection: true
        enable_static_meta_data_cache: true
        enable_static_query_cache: true

    Selective Connection Enabling: You can choose to enable the static connection only for specific connections instead of all of them:

    dama_doctrine_test:
        enable_static_connection:
            connection_a: true
  7. Troubleshoot implicit transaction commits (Savepoint errors)

    master

    If your tests execute queries that cause an implicit commit (such as DDL statements like ALTER TABLE, DROP TABLE, etc.), the bundle's transaction management will fail.

    Error Symptom: You will see a PDOException indicating a savepoint does not exist: Doctrine\DBAL\Driver\PDOException: SQLSTATE[42000]: Syntax error or access violation: 1305 SAVEPOINT DOCTRINE2_SAVEPOINT_2 does not exist

    Cause: Implicit commits break the transaction wrapper provided by the bundle. Currently, there is no way for the bundle to work with these types of queries because they cannot be rolled back once the implicit commit occurs.

  8. Skip database rollback for specific tests using #[SkipDatabaseRollback]

    master

    If you need to run a specific test without the bundle's automatic transaction rollback (e.g., for DDL queries or manual debugging), use the #[SkipDatabaseRollback] attribute. This can be applied at three levels:

    1. Class level: Skips rollback for all tests within that class.
    2. Abstract class level: Skips rollback for all tests in the class and its children.
    3. Method level: Skips rollback for only that specific test method.
    #[SkipDatabaseRollback]
    public class MyTest extends \PHPUnit\Framework\TestCase {}
    
    #[SkipDatabaseRollback]
    abstract class MyAbstractTest extends \PHPUnit\Framework\TestCase {}
    
    #[SkipDatabaseRollback]
    public function testSingleMethod() {}
    #[SkipDatabaseRollback] // applied to class, abstract class, or method
  9. Configure DAMADoctrineTestBundle settings

    master

    The DAMADoctrineTestBundle is configured via Symfony's configuration system. The extension processes settings that control caching and connection behavior. The following configuration keys are available under the dama_doctrine_test configuration tree:

    • static_meta_cache (bool): Controls whether static metadata caching is enabled.
    • static_query_cache (bool): Controls whether static query caching is enabled.
    • enable_static_connection (bool): Determines if a static connection should be used.
    • connection_keys (array): A list of keys used to manage internal driver connections. Assigning the same key will result in the same internal driver connection being re-used for both DBAL connections. Assigning different keys will result in separate internal driver connections being used for primary and replica.
    # Example configuration in config/packages/dama_doctrine_test.yaml
    dama_doctrine_test:
        static_meta_cache: true
        static_query_cache: true
        enable_static_connection: true
        connection_keys:
            - 'primary'
            - 'replica'
  10. Configure the DAMA Doctrine Test Bundle

    master

    The bundle is configured under the dama_doctrine_test key in your Symfony configuration files (e.g., config/packages/dama_doctrine_test.yaml).

    Available configuration options:

    • enable_static_connection (boolean or array): Enables static connections. If provided as an array, it maps connection names to boolean values. Defaults to true.
    • enable_static_meta_data_cache (boolean): Enables caching of metadata. Defaults to true.
    • enable_static_query_cache (boolean): Enables caching of queries. Defaults to true.
    • connection_keys (array): Defines specific connection configurations. Each key maps to either a string (the connection name) or an array defining a primary and replica setup.
    dama_doctrine_test:
        enable_static_connection: true
        enable_static_meta_data_cache: true
        enable_static_query_cache: true
        connection_keys:
            my_connection: 'connection_name'
            complex_connection:
                primary: 'primary_connection_name'
                replicas:
                    replica_1: 'replica_connection_name_1'
                    replica_2: 'replica_connection_name_2'
  11. Configure the Behat Doctrine extension

    master

    The DoctrineExtension allows you to integrate the Doctrine Test Bundle into your Behat testing suite. It registers a BehatListener which handles Doctrine-related events during test execution.

    To use this extension, add it to your behat.yml configuration file under the key dama_doctrine.

    default:
        extensions:
            DAMA\DoctrineTestBundle\Behat\ServiceContainer\DoctrineExtension:
                # Configuration options go here
  12. Manage static connections globally via StaticDriver

    master

    When setKeepStaticConnections is enabled, you can control the transaction state of all active static connections simultaneously using the following static methods on StaticDriver:

    • StaticDriver::beginTransaction(): Starts a transaction on all currently active static connections.
    • StaticDriver::rollBack(): Rolls back the transaction on all currently active static connections.
    • StaticDriver::commit(): Commits the transaction on all currently active static connections.
    use DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver;
    
    // Roll back all connections that were keyed with 'dama.connection_key'
    StaticDriver::rollBack();