2015-09-28 61 views
6

我正在开发一个没有开发环境的生产数据库副本的项目。如何测试Doctrine迁移?

有时候我们遇到了数据库迁移问题 - 他们通过开发数据库但生产/测试失败。

通常会发生Dev环境数据从使用最新实体的Fixtures中加载 - 正确填充所有表格。

有什么简单的方法可以确保主义移民(S)将通过生产?

您是否知道任何方式编写自动测试,以确保数据能够正确迁移,而无需下载生产/测试数据库并手动运行迁移?

我想避免将生产/测试数据库下载到开发机器,以便我可以检查迁移,因为数据库包含私人数据,并且它可能相当大。

+0

如果您使用的是Git,您是否认为要回到最后一个产品版本,重新创建您的数据库,fuxture,迁移并转到必须更新的版本以运行较新的migra灰。但不幸的是,唯一可靠的测试是prod数据。 –

回答

2

首先,你需要在迁移之前创造状态的样本数据库转储。对于MySQL使用mysqldump。 Postgres的pg_dump的,如:

mysqldump -u root -p mydatabase > dump-2018-02-20.sql 
pg_dump -Upostgres --inserts --encoding utf8 -f dump-2018-02-20.sql mydatabase 

然后创建为所有迁移测试一个抽象类(我假定你已经配置在config_test.yml集成测试一个单独的数据库):

abstract class DatabaseMigrationTestCase extends WebTestCase { 
    /** @var ResettableContainerInterface */ 
    protected $container; 
    /** @var Application */ 
    private $application; 

    protected function setUp() { 
     $this->container = self::createClient()->getContainer(); 
     $kernel = $this->container->get('kernel'); 
     $this->application = new Application($kernel); 
     $this->application->setAutoExit(false); 
     $this->application->setCatchExceptions(false); 

     $em = $this->container->get(EntityManagerInterface::class); 
     $this->executeCommand('doctrine:schema:drop --force'); 
     $em->getConnection()->exec('DROP TABLE IF EXISTS public.migration_versions'); 
    } 

    protected function loadDump(string $name) { 
     $em = $this->container->get(EntityManagerInterface::class); 
     $em->getConnection()->exec(file_get_contents(__DIR__ . '/dumps/dump-' . $name . '.sql')); 
    } 

    protected function executeCommand(string $command): string { 
     $input = new StringInput("$command --env=test"); 
     $output = new BufferedOutput(); 
     $input->setInteractive(false); 
     $returnCode = $this->application->run($input, $output); 
     if ($returnCode != 0) { 
      throw new \RuntimeException('Failed to execute command. ' . $output->fetch()); 
     } 
     return $output->fetch(); 
    } 

    protected function migrate(string $toVersion = '') { 
     $this->executeCommand('doctrine:migrations:migrate ' . $toVersion); 
    } 
} 

实例迁移测试:

class Version20180222232445_MyMigrationTest extends DatabaseMigrationTestCase { 
    /** @before */ 
    public function prepare() { 
     $this->loadDump('2018-02-20'); 
     $this->migrate('20180222232445'); 
    } 

    public function testMigratedSomeData() { 
     $em = $this->container->get(EntityManagerInterface::class); 
     $someRow = $em->getConnection()->executeQuery('SELECT * FROM myTable WHERE id = 1')->fetch(); 
     $this->assertEquals(1, $someRow['id']); 
     // check other stuff if it has been migrated correctly 
    } 
} 
1

我已经想出了原理迁移的简单“冒烟测试”。

我PHPUnit的测试perfoming以下步骤:

  • 跌落试验DB
  • 创建测试DB
  • 负载迁移(创建模式)
  • 负载夹具(模仿生产数据)
  • 迁移to some older version
  • 移回到最新版本

这样我可以测试我们最近遇到的主要问题。

的PHPUnit测试实例可以在我的博客上找到:http://damiansromek.pl/2015/09/29/how-to-test-doctrine-migrations/

+2

您的链接会引发404错误... – Hornth