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:
/**
* @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...
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/127
Well, I solved it by replacing the MySqlPlatform::getTruncateTableSQL
method like:
config_test.ymldoctrine: dbal: driver_class: Your\OwnBundle\DBAL\Driver ...
src/Your/OwnBundle/DBAL/Driver.php
<?php
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
<?php
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:
/**
* @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.