I've been following a BDD approach using Behat to develop a RESTful API on my current project and wanted to fully isolate the data base from feature to feature, so first I tried with:php
/** * @BeforeFeature */ public static function beforeFeature(BeforeFeatureScope $scope) { echo shell_exec('app/console doctrine:schema:drop --env=test --force'); echo shell_exec('app/console doctrine:schema:create --env=test'); echo shell_exec('app/console doctrine:fixtures:load --env=test -n'); }
and it was pretty slow, in my case it was taking an average of 1,5s...git
Reading the DoctrineFixturesBundle help I found a nice --purge-with-truncate
flag, but TA DAN, it was failing with this issue: https://github.com/doctrine/data-fixtures/pull/127github
Well, I solved it by replacing the MySqlPlatform::getTruncateTableSQL
method like:shell
config_test.yml
doctrine: dbal: driver_class: Your\OwnBundle\DBAL\Driver ...
app
src/Your/OwnBundle/DBAL/Driver.php
<?phpthis
namespace Your\OwnBundle\DBAL; use Doctrine\DBAL\Driver\PDOMySql\Driver as BaseDriver; class Driver extends BaseDriver { /** * {@inheritdoc} */ public function getDatabasePlatform() { return new Platform(); } }
src/Your/OwnBundle/DBAL/Platform.php
<?phpspa
namespace Your\OwnBundle\DBAL; use Doctrine\DBAL\Platforms\MySqlPlatform; class Platform extends MySqlPlatform { /** * {@inheritdoc} */ public function getTruncateTableSQL($tableName, $cascade = false) { return sprintf('SET foreign_key_checks = 0;TRUNCATE %s;SET foreign_key_checks = 1;', $tableName); } }
And finally:code
/** * @BeforeFeature */ public static function beforeFeature(BeforeFeatureScope $scope) { echo shell_exec('app/console doctrine:fixtures:load --env=test --purge-with-truncate -n'); }
It's hacky, I know, but it does the job for the tests and cuts down the average time to 0,4s.orm