イントロダクションIntroduction
データベース駆動型アプリケーションのテストを容易にするため、Laravelはさまざまな便利なツールとアサートを提供しています。それに加えて、Laravelモデルのファクトリ(テスト用インスタンスの生成)とシーダ(初期データ設定)により、アプリケーションのEloquentモデルとリレーションを使用し、テストデータベースレコードを簡単に作成できます。これらの強力な機能のすべてについて、以降のドキュメントで説明します。Laravel provides a variety of helpful tools and assertions to make it easier to test your database driven applications. In addition, Laravel model factories and seeders make it painless to create test database records using your application's Eloquent models and relationships. We'll discuss all of these powerful features in the following documentation.
各テスト後のデータベースリセットResetting the Database After Each Test
先へ進む前に、以前のテストデータが後続のテストに干渉しないように、各テストの後にデータベースをリセットする方法について説明しましょう。Laravelに含まれているIlluminate\Foundation\Testing\RefreshDatabase
トレイトがこれを処理します。テストクラスでトレイトを使用するだけです。Before proceeding much further, let's discuss how to reset your database after each of your tests so that data from a previous test does not interfere with subsequent tests. Laravel's included Illuminate\Foundation\Testing\RefreshDatabase
trait will take care of this for you. Simply use the trait on your test class:
<?php
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('basic example', function () {
$response = $this->get('/');
// ...
});
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
use RefreshDatabase;
/**
* 基本的な機能テストの例
*/
public function test_basic_example(): void
{
$response = $this->get('/');
// ...
}
}
Illuminate\Foundation\Testing\RefreshDatabase
トレイトは、スキーマが最新であれば、データベースをマイグレートしません。その代わりに、データベーストランザクション内でテストを実行するだけです。したがって、このトレイトを使用しないテストケースによってデータベースに追加されたレコードは、まだデータベースに残っている可能性があります。The Illuminate\Foundation\Testing\RefreshDatabase
trait does not migrate your database if your schema is up to date. Instead, it will only execute the test within a database transaction. Therefore, any records added to the database by test cases that do not use this trait may still exist in the database.
データベースを完全にリセットしたい場合は、代わりにIlluminate\Foundation\Testing\DatabaseMigrations
、またはIlluminate\Foundation\Testing\DatabaseTruncation
トレイトを使用してください。しかし、両選択肢とも、RefreshDatabase
トレイトよりもかなり遅いです。If you would like to totally reset the database, you may use the Illuminate\Foundation\Testing\DatabaseMigrations
or Illuminate\Foundation\Testing\DatabaseTruncation
traits instead. However, both of these options are significantly slower than the RefreshDatabase
trait.
モデルファクトリModel Factories
テスト時、テストを実行する前にデータベースへレコードを挿入する必要がある場合があると思います。このようなテストデータ作成時、各カラムの値を手作業で指定する代わりに、Laravelではモデルファクトリを使用し、デフォルトの属性セットを各Eloquentモデルに対して定義できます。When testing, you may need to insert a few records into your database before executing your test. Instead of manually specifying the value of each column when you create this test data, Laravel allows you to define a set of default attributes for each of your Eloquent models[/docs/{{version}}/eloquent] using model factories[/docs/{{version}}/eloquent-factories].
モデルを生成するモデルファクトリの作成と利用の詳細は、完全なモデルファクトリドキュメントを参照してください。モデルファクトリを定義したら、テスト内でそのファクトリを利用してモデルを作成できます。To learn more about creating and utilizing model factories to create models, please consult the complete model factory documentation[/docs/{{version}}/eloquent-factories]. Once you have defined a model factory, you may utilize the factory within your test to create models:
use App\Models\User;
test('models can be instantiated', function () {
$user = User::factory()->create();
// ...
});
use App\Models\User;
public function test_models_can_be_instantiated(): void
{
$user = User::factory()->create();
// ...
}
シーダの実行Running Seeders
機能テスト中にデータベースシーダ(初期値設定)を使用してデータベースへデータを入力する場合は、seed
メソッドを呼び出してください。seed
メソッドはデフォルトで、DatabaseSeeder
を実行します。これにより、他のすべてのシーダが実行されます。または、特定のシーダクラス名をseed
メソッドに渡します。If you would like to use database seeders[/docs/{{version}}/seeding] to populate your database during a feature test, you may invoke the seed
method. By default, the seed
method will execute the DatabaseSeeder
, which should execute all of your other seeders. Alternatively, you pass a specific seeder class name to the seed
method:
<?php
use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('orders can be created', function () {
// Run the DatabaseSeeder...
$this->seed();
// Run a specific seeder...
$this->seed(OrderStatusSeeder::class);
// ...
// Run an array of specific seeders...
$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
{
// データベース初期値設定実行
$this->seed();
// 特定のシーダの実行
$this->seed(OrderStatusSeeder::class);
// ...
// 配列で特定のシーダを実行
$this->seed([
OrderStatusSeeder::class,
TransactionStatusSeeder::class,
// ...
]);
}
}
あるいは、RefreshDatabase
トレイトを使用する各テストの前に、自動的にデータベースをシードするようにLaravelに指示することもできます。これを実現するには、テストの基本クラスに$seed
プロパティを定義します。Alternatively, you may instruct Laravel to automatically seed the database before each test that uses the RefreshDatabase
trait. You may accomplish this by defining a $seed
property on your base test class:
<?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
プロパティを定義し,実行したい特定のシーダーを指定できます。When the $seed
property is true
, the test will run the Database\Seeders\DatabaseSeeder
class before each test that uses the RefreshDatabase
trait. However, you may specify a specific seeder that should be executed by defining a $seeder
property on your test class:
use Database\Seeders\OrderStatusSeeder;
/**
* 各テストの前に特定のシーダーを実行
*
* @var string
*/
protected $seeder = OrderStatusSeeder::class;
利用可能なアサートAvailable Assertions
Laravelでは、PestやPHPUnitの機能テスト用に、いくつかのデータベースアサートを用意しています。以下に、それぞれのアサートについて説明します。Laravel provides several database assertions for your Pest[https://pestphp.com] or PHPUnit[https://phpunit.de] feature tests. We'll discuss each of these assertions below.
assertDatabaseCountassertDatabaseCount
データベース内のテーブルに指定した数のレコードが含まれていることをアサートします。Assert that a table in the database contains the given number of records:
$this->assertDatabaseCount('users', 5);
assertDatabaseHasassertDatabaseHas
データベース内のテーブルに、指定したキー/値クエリの制約に一致するレコードが含まれていることをアサートします。Assert that a table in the database contains records matching the given key / value query constraints:
$this->assertDatabaseHas('users', [
'email' => 'sally@example.com',
]);
assertDatabaseMissingassertDatabaseMissing
データベース内のテーブルに、指定したキー/値クエリの制約に一致するレコードが含まれていないことをアサートします。Assert that a table in the database does not contain records matching the given key / value query constraints:
$this->assertDatabaseMissing('users', [
'email' => 'sally@example.com',
]);
assertSoftDeletedassertSoftDeleted
assertSoftDeleted
メソッドは、指定したEloquentモデルが「ソフトデリート」されたことをアサートします。The assertSoftDeleted
method may be used to assert a given Eloquent model has been "soft deleted":
$this->assertSoftDeleted($user);
assertNotSoftDeletedassertNotSoftDeleted
assertNotSoftDeleted
メソッドは、指定Eloquentモデルが、「ソフトデリート」されていないことをアサートします。The assertNotSoftDeleted
method may be used to assert a given Eloquent model hasn't been "soft deleted":
$this->assertNotSoftDeleted($user);
assertModelExistsassertModelExists
指定モデルがデータベースに存在することをアサートします。Assert that a given model exists in the database:
use App\Models\User;
$user = User::factory()->create();
$this->assertModelExists($user);
assertModelMissingassertModelMissing
指定モデルがデータベースに存在しないことをアサートします。Assert that a given model does not exist in the database:
use App\Models\User;
$user = User::factory()->create();
$user->delete();
$this->assertModelMissing($user);
expectsDatabaseQueryCountexpectsDatabaseQueryCount
expectsDatabaseQueryCount
メソッドは、テスト中に実行されるであろうデータベースクエリの総数をアサートします。実際に実行されたクエリの数がこの期待値と一致しない場合、テストは失敗します。The expectsDatabaseQueryCount
method may be invoked at the beginning of your test to specify the total number of database queries that you expect to be run during the test. If the actual number of executed queries does not exactly match this expectation, the test will fail:
$this->expectsDatabaseQueryCount(5);
// テスト…