WEB/システム/IT技術ブログ

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

B!

Comment

コメントはありません

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

Monthly Archives