Symfony:刷新测试数据库以进行phpunit测试,并在添加的fixture上重置自动增量



我想在每次运行bin/phpunit时创建一个新的内存sqlite测试数据库来运行我的测试。到目前为止,我发现的解决方案清空了测试数据库,但当我添加fixture时,它们的id从擦除前的最后一个自动增量开始。

对于任何面临这个问题的人,我发布了一个从这里开始的解决方案(https://www.sitepoint.com/quick-tip-testing-symfony-apps-with-a-disposable-database/)以及一些调查和试错:

条令会议

#api/config/packages/test/doctrine.yaml
doctrine:
dbal:
driver: 'pdo_sqlite'
memory:  true
charset: UTF8

带数据库的WebTestCase

<?php
namespace AppTests;
use DoctrineCommonDataFixturesExecutorORMExecutor;
use DoctrineCommonDataFixturesLoader;
use DoctrineCommonDataFixturesPurgerORMPurger;
use DoctrineORMEntityManager;
use DoctrineORMToolsSchemaTool;
use MetadataClassMetadata;
use SymfonyBundleFrameworkBundleKernelBrowser;
use SymfonyBundleFrameworkBundleTestWebTestCase;
class WebTestCaseWithDatabase extends WebTestCase
{
/**
* @var KernelBrowser
*/
protected $client;
/**
* @var EntityManager
*/
protected $em;
/**
* @var SchemaTool
*/
protected $schemaTool;
/**
* @var ClassMetadata[]
*/
protected $metaData;

protected function setUp()
{
parent::setUp();
// This is tricky. You need to boot the kernel to create the DDBB.                   
// But if you boot it with static::bootKernel(),                        
// an error will be thrown if you create the client in your tests, 
// because static::createClient() tries boot again the kernel.
// That's why I create the client and boot the kernel only once here.
$this->client = static::createClient();
// Make sure we are in the test environment
if ('test' !== self::$kernel->getEnvironment()) {
throw new LogicException('Tests cases with fresh database must be executed in the test environment');
}
// Get the entity manager from the service container
$this->em = self::$kernel->getContainer()->get('doctrine')->getManager();
// Run the schema update tool using our entity metadata
$this->metaData = $this->em->getMetadataFactory()->getAllMetadata();
$this->schemaTool = new SchemaTool($this->em);
$this->schemaTool->updateSchema($this->metaData);
}
// Helper function to add fixtures
public function addFixture($className)
{
$loader = new Loader();
$loader->addFixture(new $className);
$purger = new ORMPurger($this->em);
$executor = new ORMExecutor($this->em, $purger);
$executor->execute($loader->getFixtures());
}
// Trunkate the whole database on tearDown
protected function tearDown(): void
{
parent::tearDown();
// Purge all the fixtures data when the tests are finished
$purger = new ORMPurger($this->em);
// Purger mode 2 truncates, resetting autoincrements
$purger->setPurgeMode(2);
$purger->purge();
}
}

示例测试

<?php
namespace AppTests;
use AppDataFixturesExampleFixture;
class ExampleTest extends WebTestCaseWithDatabase
{
protected function setUp()
{
parent::setUp();
// Add whatever fixtures you need here
$this->addFixture(ExampleFixture::class);
}
// Add your tests 
public function test_something()
{
// test code
}
}

我希望它能有所帮助!

如果你正在寻找一个包来为你做这件事,dmaicher/doctrine测试包可以自动完成。每个测试都将针对一个新的数据库运行。

最新更新