2015-09-28 60 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