データベーステスト¶
イントロダクション¶
Laravelは、データベース駆動のアプリケーションを簡単にテストできるように、さまざまな便利なツールとアサーションを提供しています。さらに、Laravelのモデルファクトリとシーダーを使用すると、アプリケーションのEloquentモデルとリレーションを使用して、テストデータベースレコードを簡単に作成できます。これらの強力な機能については、以下のドキュメントで説明します。
各テスト後のデータベースリセット¶
さらに進む前に、各テスト後にデータベースをリセットする方法について説明しましょう。これにより、前のテストのデータが後続のテストに干渉しないようになります。Laravelに含まれるIlluminate\Foundation\Testing\RefreshDatabase
トレイトが、これを処理します。テストクラスでトレイトを使用するだけです:
Illuminate\Foundation\Testing\RefreshDatabase
トレイトは、スキーマが最新の場合、データベースをマイグレートしません。代わりに、データベーストランザクション内でテストを実行するだけです。したがって、このトレイトを使用しないテストケースによってデータベースに追加されたレコードは、データベースに残る可能性があります。
データベースを完全にリセットしたい場合は、代わりにIlluminate\Foundation\Testing\DatabaseMigrations
またはIlluminate\Foundation\Testing\DatabaseTruncation
トレイトを使用できます。ただし、これらのオプションはRefreshDatabase
トレイトよりも大幅に遅くなります。
モデルファクトリ¶
テストを行う際、テストを実行する前にデータベースにいくつかのレコードを挿入する必要があるかもしれません。このテストデータを作成する際に、各列の値を手動で指定する代わりに、Laravelではモデルファクトリを使用して、各Eloquentモデルのデフォルト属性のセットを定義できます。
モデルファクトリの作成と使用方法について詳しくは、完全なモデルファクトリのドキュメントを参照してください。モデルファクトリを定義したら、テスト内でファクトリを使用してモデルを作成できます:
シーダーの実行¶
機能テスト中にデータベースシーダーを使用してデータベースをデータで埋めたい場合は、seed
メソッドを呼び出すことができます。デフォルトでは、seed
メソッドはDatabaseSeeder
を実行し、これにより他のすべてのシーダーが実行されます。または、特定のシーダークラス名をseed
メソッドに渡すこともできます:
<?php
use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('orders can be created', function () {
// DatabaseSeederを実行...
$this->seed();
// 特定のシーダーを実行...
$this->seed(OrderStatusSeeder::class);
// ...
// 特定のシーダーの配列を実行...
$this->seed([
OrderStatusSeeder::class,
TransactionStatusSeeder::class,
// ...
]);
});
<?php
namespace Tests\Feature;
use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
use RefreshDatabase;
/**
* 新しい注文の作成テスト。
*/
public function test_orders_can_be_created(): void
{
// DatabaseSeederを実行...
$this->seed();
// 特定のシーダーを実行...
$this->seed(OrderStatusSeeder::class);
// ...
// 特定のシーダーの配列を実行...
$this->seed([
OrderStatusSeeder::class,
TransactionStatusSeeder::class,
// ...
]);
}
}
または、RefreshDatabase
トレイトを使用する各テストの前に、Laravelにデータベースを自動的にシードするように指示できます。これは、ベーステストクラスに$seed
プロパティを定義することで実現できます:
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
/**
* 各テストの前にデフォルトのシーダーを実行するかどうかを示します。
*
* @var bool
*/
protected $seed = true;
}
$seed
プロパティがtrue
の場合、RefreshDatabase
トレイトを使用する各テストの前にDatabase\Seeders\DatabaseSeeder
クラスが実行されます。ただし、テストクラスに$seeder
プロパティを定義することで、特定のシーダーを実行するように指定できます:
use Database\Seeders\OrderStatusSeeder;
/**
* 各テストの前に実行する特定のシーダー。
*
* @var string
*/
protected $seeder = OrderStatusSeeder::class;
利用可能なアサーション¶
Laravelは、PestまたはPHPUnitの機能テスト用にいくつかのデータベースアサーションを提供しています。以下では、これらの各アサーションについて説明します。
assertDatabaseCount¶
データベース内のテーブルに指定された数のレコードが含まれていることをアサートします:
$this->assertDatabaseCount('users', 5);
assertDatabaseHas¶
データベース内のテーブルに、指定されたキー/値のクエリ制約に一致するレコードが含まれていることをアサートします:
$this->assertDatabaseHas('users', [
'email' => 'sally@example.com',
]);
assertDatabaseMissing¶
データベース内のテーブルに、指定されたキー/値のクエリ制約に一致するレコードが含まれていないことをアサートします:
$this->assertDatabaseMissing('users', [
'email' => 'sally@example.com',
]);
assertSoftDeleted¶
assertSoftDeleted
メソッドは、指定されたEloquentモデルが「ソフトデリート」されたことをアサートするために使用できます:
$this->assertSoftDeleted($user);
assertNotSoftDeleted¶
assertNotSoftDeleted
メソッドは、指定されたEloquentモデルが「ソフトデリート」されていないことをアサートするために使用できます:
$this->assertNotSoftDeleted($user);
assertModelExists¶
指定されたモデルがデータベースに存在することをアサートします:
use App\Models\User;
$user = User::factory()->create();
$this->assertModelExists($user);
assertModelMissing¶
指定されたモデルがデータベースに存在しないことをアサートします:
use App\Models\User;
$user = User::factory()->create();
$user->delete();
$this->assertModelMissing($user);
expectsDatabaseQueryCount¶
expectsDatabaseQueryCount
メソッドは、テストの開始時に呼び出され、テスト中に実行されるデータベースクエリの総数を指定できます。実際のクエリ数がこの期待値と一致しない場合、テストは失敗します:
$this->expectsDatabaseQueryCount(5);
// テスト...