hgraca / doctrine-test-db-regeneration-bundle
Symfony 2/3/4 bundle to generate the test DB (if needed) for every test suite run or test method run.
Installs: 6 243
Dependents: 0
Suggesters: 0
Security: 0
Stars: 4
Watchers: 2
Forks: 2
Open Issues: 0
Requires
- php: ^7.1
- doctrine/data-fixtures: ^1.1
- doctrine/dbal: ^2
- doctrine/doctrine-bundle: ^1
- doctrine/doctrine-fixtures-bundle: ^3
- doctrine/doctrine-migrations-bundle: ^1.3
- doctrine/orm: ^2
- symfony/framework-bundle: ^2.7|^3.0|^4.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.0
- mockery/mockery: v1.0.0-alpha1
- phpunit/php-code-coverage: ^5
- phpunit/phpunit: ^6.0
- roave/security-advisories: dev-master
README
This is a Symfony 2/3/4 bundle, inspired on some code @lcobucci wrote back in 2017, to generate the test DB (if needed) for every test suite run or test method run.
When we have Integration tests that need to use a DB, the best practice is to have the tests use a SQLite DB for those tests. However, keeping the SQLite DB file in our repo is not a good practice, and using the same file for all tests neither, because tests should run in isolation from each other.
This bundle provides the functionality to generate the test DB SQLite file, and regenerate it for every test that needs a DB.
By default, at the beginning of a test run it will create a test database, based on the Doctrine fixtures, and a serialized fixtures object.
After generating those initial files, it will copy the backup DB SQLite file into the path of the DB SQLite file being
used by the tests, but only before the tests implementing the tag interface DatabaseAwareTestInterface
so that we
don't regenerate the DB for tests that don't need it.
This last functionality, however, can be disabled so that we can use this bundle with another bundle like the DAMA\DoctrineTestBundle, which provides similar functionality which will probably give you better performance. In such case, this bundle is only useful for generating the initial test DB.
Installation & Setup
-
install via composer
composer require --dev hgraca/doctrine-test-db-regeneration-bundle
-
Enable the bundle for your test environment in your
AppKernel.php
, ie:if (in_array($env, ['dev', 'test'])) { ... if ($env === 'test') { $bundles[] = new Hgraca\DoctrineTestDbRegenerationBundle\HgracaDoctrineTestDbRegenerationBundle(); } }
-
The bundle exposes a configuration that looks like this by default:
hgraca_doctrine_test_db_regeneration: doctrine_service_id: 'doctrine' fixtures_loader_service_id: 'doctrine.fixtures.loader' test_db_bkp_path: '%kernel.cache_dir%/test.bkp.db' # The list of extra services to add to the container, # in case you want to reuse this already built container. extra_service_list: []
-
Add the PHPUnit test listener in your xml config (e.g.
app/phpunit.xml
)<phpunit> ... <listeners> <!-- At the beginning of every test run, it will generate the test DB and create a backup of it and a backup of the fixtures references. At the beginning of every test it will recover the test DB backup. --> <listener class="\Hgraca\DoctrineTestDbRegenerationBundle\EventSubscriber\DbRegenerationPHPUnitEventSubscriber" /> </listeners> </phpunit>
There are a few options you can use to tweak how it works. Below you can see the options with their default values:
<phpunit> ... <listeners> <listener class="\Hgraca\DoctrineTestDbRegenerationBundle\EventSubscriber\DbRegenerationPHPUnitEventSubscriber"> <arguments> <integer>1</integer> <!-- $shouldRemoveDbAfterEveryTest --> <integer>1</integer> <!-- $shouldRegenerateOnEveryTest --> <integer>0</integer> <!-- $shouldReuseExistingDbBkp --> </arguments> </listener> </listeners> </phpunit>
I strongly advise using DAMA\DoctrineTestBundle as well, as in a platform with 1596 integration tests, it reduced the test execution time from 2m to 46s.
If you are using DAMA\DoctrineTestBundle you will want to set it up like this:
<phpunit> ... <listeners> <!-- Since we are using DAMA\DoctrineTestBundle we don't need to recover the test DB at every test run, so we turn it off. However, this listener must go first, so it creates the test DB before DAMA\DoctrineTestBundle tries to use it. --> <listener class="\Hgraca\DoctrineTestDbRegenerationBundle\EventSubscriber\DbRegenerationPHPUnitEventSubscriber"> <arguments> <integer>0</integer> <!-- $shouldRemoveDbAfterEveryTest --> <integer>0</integer> <!-- $shouldRegenerateOnEveryTest --> </arguments> </listener> <!-- it begins a database transaction before every testcase and rolls it back after the test finished, so tests can manipulate the database without affecting other tests --> <listener class="\DAMA\DoctrineTestBundle\PHPUnit\PHPUnitListener" /> </listeners> </phpunit>
-
Make your tests, that need DB access, implement the tag interface
DatabaseAwareTestInterface
, so it only recovers the DB for those tests. -
Done! From now on the test database will be generated (if needed) at the beginning of running the tests, and at the beginning of every test tagged as
DatabaseAwareTestInterface
, if you did not disable this feature.
Available commands
Run the test suites:
make test
Create th test coverage report:
make coverage
Fix the code standards:
make cs-fix
Manage the project dependencies:
make dep-install make dep-update
Build the docker container used for testing:
make build-container-tst