Laravelでデータベースのテスト
Laravelでデータベースをテストします。
今回は、新規プロジェクトではなく、既存プロジェクトをテストする前提で進めていきます。
- PHP 8.0.25
- Laravel 9.52.0
- SQLite
テスト用のDBを用意する
データベースをテストする際、安全なDBが必要です。
つまり、テストで本番環境のDBを使うわけにはいきません。また、場合によっては開発環境のDBを汚すこともあると思います。
そこで、今回はテスト用のDBを用意してみます。
例えば、SQLiteで用意したテスト用DB「testing」を使用します。
まず、空のファイル「/database/database_test.sqlite」を用意します。Linux系であればtouchコマンド、Windowsであればテキストファイルを新規作成します。
次に「/config/database.php」を開きます。
「sqlite」ブロックをコピペして「testing」にリネームします。
... 'testing' => [ 'driver' => 'sqlite', 'url' => env('DATABASE_URL'), 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), ], ...
さらに、今回はローカルのみでの使用なので環境変数を使いません。databaseには先ほど用意したファイル名「database_test.sqlite」に書き換えます。
... 'testing' => [ 'driver' => 'sqlite', 'database' => database_path('database_test.sqlite'), 'prefix' => '', 'foreign_key_constraints' => true, ], ...
次に「phpunit.xml」を開きます。
PHPUnitテスト実行時のみ、テスト用のデータベースに接続するために「DB_CONNECTION」に用意したデータベース名を指定します。
... <env name="DB_CONNECTION" value="testing"/> ...
DBの設定は以上です。
テーブルを作成する
既存プロジェクトの場合、マイグレーションが存在すると思います。
そのマイグレーションを使用して、テスト用DBにテーブルを作成します。
オプションでDB設定「testing」を指定する点に注意しましょう。
> php artisan migrate:refresh --database=testing WARN Migration table not found. INFO Preparing database. Creating migration table ............................................................................................................... 7ms DONE INFO Running migrations. ...
テストコード
テストコードの例です。
店舗情報テーブル「shop」のユニットテスト「ShopTest.php」です。
use App\Models\Shop; class ShopTest extends TestCase { // テスト前にDBをリセット(テーブルを空に)します use RefreshDatabase; /** * モデルテスト */ public function test_shop_model_is_working(): void { // ファクトリでダミーデータ作成 $data = [ 'name' => 'heroのお店' ]; Shop::factory()->create($data); // レコードが保存されていること $shop = Shop::find(1); $this->assertDatabaseHas('shop', $data); // レコードが更新されていること $shop->name = "ショップへろ"; $shop->save(); $data['name'] = "ショップへろ"; $this->assertDatabaseHas('shop', $data); // レコードが削除されていること $shop->delete(); $this->assertSoftDeleted('shop', $data); } }
解説はコメントの通りです。
ダミーデータを作成するファクトリは別途用意済みとします。
通常、テーブルにレコードが存在しないテストは「assertDatabaseMissing」で実行しますが、今回はソフトデリートを使用しているので「assertSoftDeleted」を使います。
以上です。もっと良いコードがあればご指摘いただきたいですw
コメントする