Laravel :: phpunit with clean database.
Laravel + postgresSQLを使ったサイトで unit test を書いてたが、既存のデータベースを使うと、テストが意図しない挙動になることがあったので、汚れていないDBを使いたくなったので、調べてやってみたら、意外と詰まってしまったという話。
環境
- laravel 5.x
- PostgreSQL
sqlite in memory database を使う方法
config/database.php
環境変数で default 値を差し替えれるようにする
'default' => env('DB_DEFAULT', 'pgsql'),
config/database.php
memory database の定義を作る
'sqlite_testing' => [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
],
phpunit.xml
環境変数追加。環境変数を与える方法は別に何でも良い。
~~~~~~~~~~~~~
<env name="DB_DEFAULT" value="sqlite_testing"/>
</php>
</phpunit>
TestCase.php
都度migrateをするようにする。
public function setUp()
{
parent::setUp();
$this->artisan('migrate');
$this->artisan('db:seed');
}
public function tearDown()
{
$this->artisan('migrate:reset');
}
これで上手くいく人は上手くいく。
Sqliteでエラーがでる場合の対処1
Driver not found
[Symfony\Component\Debug\Exception\FatalErrorException]
Class 'Doctrine\DBAL\Driver\PDOSqlite\Driver' not found
が出たら。
cmposer に
"doctrine/dbal": "^2.5"
ALTER TABLE SYNTAX ERROR
さらにエラーが出る。
ALTER TABLE が syntax エラーと migration 中に出る。
ここからヒントをもらう。
以下のスレッドの中で、SQL Features That SQLite Does Not Implement [sqlite.org] を参照。つまり、sqliteで実装されていないので、エラーになっている。
ここを参考に、
エラーがでない内容の migration だけを行い、
そのsqlite file をテスト前にコピーして、テスト後破棄するというもの。
少々面倒。
また以下問題も見つかる。
migration 中にエラーが出たら、エラーが出たファイルを消して、migration を終了させた後、テストを流してみたが、特定のカラムが無いというエラーが起きた。
一つの migration ファイルの中で、ADD COLUMN と DROP COLUMN 両方を入れているとエラーにならず、追加もされない。
Sqliteでエラーがでる場合の対処2
sqlite を諦め、PostgreSQL に一時的な testdb を作成し、
そちらでテストを行い、終了後は drop database する。
script を書きそれを実行した。
psql -U postgres -c "CREATE DATABASE testdb"
php artisan migrate --database=pgsql_testing
php artisan db:seed --database=pgsql_testing
phpunit -c phpunit.xml "$@"
psql -U postgres -c "DROP DATABASE testdb"
これでようやく上手くいった。