dama/doctrine-test-bundle 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

dama/doctrine-test-bundle

Composer 安装命令:

composer require --dev dama/doctrine-test-bundle

包简介

Symfony bundle to isolate doctrine database tests and improve test performance

README 文档

README

PHP Version Stable release

What does it do? 😊

This bundle provides features that help you run your Symfony-framework-based App's testsuite more efficiently with isolated tests.

It provides a StaticDriver that will wrap your originally configured Driver class (like DBAL\Driver\PDOMysql\Driver) and keeps a database connection statically in the current php process.

With the help of a PHPUnit extension class it will begin a transaction before every testcase and roll it back again after the test finished for all configured DBAL connections. This results in a performance boost as there is no need to rebuild the schema, import a backup SQL dump or re-insert fixtures before every testcase. As long as you avoid issuing DDL queries that might result in implicit transaction commits (Like ALTER TABLE, DROP TABLE etc; see https://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis) your tests will be isolated and all see the same database state.

It also includes a Psr6StaticArrayCache that will be automatically configured as meta data & query cache for all EntityManagers. This improved the speed and memory usage for my testsuites dramatically! This is especially beneficial if you have a lot of tests that boot kernels (like Controller tests or ContainerAware tests) and use Doctrine entities.

How to install and use this Bundle?

  1. install via composer
composer require --dev dama/doctrine-test-bundle
  1. If you're not using Flex, enable the bundle by adding the class to bundles.php
<?php
// config/bundles.php

return [
    //...
    DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
    //...
];
  1. Starting from version 8 and only when using DBAL < 4 you need to make sure you have use_savepoints enabled on your doctrine DBAL configuration for all relevant connections:
doctrine:
   dbal:
       connections:
           default:
               use_savepoints: true

Using the Bundle with PHPUnit

  1. Add the Extension to your PHPUnit XML config

    <phpunit>
        ...
        <extensions>
            <bootstrap class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension" />
        </extensions>
    </phpunit>
  2. Make sure you also have phpunit/phpunit available as a dev dependency (versions 11, 12 and 13 are supported with the built-in extension) to run your tests. Alternatively this bundle is also compatible with symfony/phpunit-bridge and its simple-phpunit script. (Note: you may need to make sure the phpunit-bridge requires the correct PHPUnit 10+ Version using the environment variable SYMFONY_PHPUNIT_VERSION).

  3. That's it! From now on whatever changes you do to the database within each single testcase (be it a WebTestCase or a KernelTestCase or any custom test) are automatically rolled back for you 😊

Skipping the transactional database connection handling for specific tests

With PHPUnit you can skip this bundle's database rollback handling for specific tests if needed:

#[SkipDatabaseRollback] // this will skip it for all tests in a class
public class MyTest extends \PHPUnit\Framework\TestCase {}

#[SkipDatabaseRollback] // also supported on (abstract) parent classes. So all tests in child classes will skip the rollback logic.
abstract class MyAbstractTest extends \PHPUnit\Framework\TestCase {}

#[SkipDatabaseRollback] // this will skip it for only one test method
public function MyTest() {}

Using the Bundle with Behat

Enable the extension in your Behat config (e.g. behat.yml)

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

That's it! From now on whatever changes you do to the database within each scenario are automatically rolled back for you.

Please note that this is only works if the tests are executed in the same process as Behat. This means it cannot work when using e.g. Selenium to call your application.

Configuration

The bundle exposes a configuration that looks like this by default:

dama_doctrine_test:
    enable_static_connection: true
    enable_static_meta_data_cache: true
    enable_static_query_cache: true

Setting enable_static_connection: true means it will enable it for all configured doctrine dbal connections.

You can selectively only enable it for some connections if required:

dama_doctrine_test:
    enable_static_connection:
        connection_a: true

Controlling how connections are kept statically in the current php process

By default, every configured doctrine DBAL connection will have its own driver connection that is managed in the current php process. In case you need to customize this behavior you can choose different "connection keys" that are used to select driver connections.

Example for 2 connections that will re-use the same driver connection instance:

doctrine:
    dbal:
        connections:
            default:
                url: '%database.url1%'

            foo:
                url: '%database.url2%'

dama_doctrine_test:
    connection_keys:
        # assigning the same key will result in the same internal driver connection being re-used for both DBAL connections
        default: custom_key
        foo: custom_key

Since v8.1.0: For connections with read/write replicas the bundle will use the same underlying driver connection by default for the primary and also for replicas. This addresses an issue where inconsistencies happened when reading/writing to different connections. This can also be customized as follows:

doctrine:
    dbal:
        connections:
            default:
                url: '%database.url%'
                replicas:
                    replica_one:
                        url: '%database.url_replica%'

dama_doctrine_test:
    connection_keys:
        # assigning different keys will result in separate internal driver connections being used for primary and replica
        default:
            primary: custom_key_primary
            replicas:
                replica_one: custom_key_replica

Example

An example usage can be seen within the functional tests included in this bundle: https://github.com/dmaicher/doctrine-test-bundle/tree/master/tests

This bundle is also used on the official Symfony Demo testsuite: https://github.com/symfony/demo

Debugging

Sometimes it can be useful to be able to debug the database contents when a test failed. As normally all changes are rolled back automatically you can do this manually:

public function testMyTestCaseThatINeedToDebug()
{
    // ... something thats changes the DB state
    \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver::commit();
    die;
    // now the DB changes are actually persisted and you can debug them
}

Troubleshooting

In case you are running (maybe without knowing it) queries during your tests that are implicitly committing any open transaction (see https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html for example) you might see an error like this:

Doctrine\DBAL\Driver\PDOException: SQLSTATE[42000]: Syntax error or access violation: 1305 SAVEPOINT DOCTRINE2_SAVEPOINT_2 does not exist

Currently there is no way for this bundle to work with those queries as they simply cannot be rolled back after the test case finished.

See also #58

dama/doctrine-test-bundle 适用场景与选型建议

dama/doctrine-test-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 41.11M 次下载、GitHub Stars 达 1.19k, 最近一次更新时间为 2016 年 03 月 19 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「symfony」 「performance」 「testing」 「doctrine」 「tests」 「isolation」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 dama/doctrine-test-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 dama/doctrine-test-bundle 我们能提供哪些服务?
定制开发 / 二次开发

基于 dama/doctrine-test-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 41.11M
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1186
  • 点击次数: 27
  • 依赖项目数: 162
  • 推荐数: 4

GitHub 信息

  • Stars: 1185
  • Watchers: 8
  • Forks: 62
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2016-03-19