Readouble

Laravel 5.3 データベースのテスト

イントロダクションIntroduction

Laravelでは、データベースを駆動するアプリケーションのテストを簡単にできる、便利で様々なツールを用意しています。その一つは、指定した抽出条件に一致するデータがデータベース中に存在するかをアサートする、seeInDatabaseヘルパです。たとえば、userテーブルの中にemailフィールドがsally@example.comの値のレコードが存在するかを確認したいとしましょう。次のようにテストできます。Laravel provides a variety of helpful tools to make it easier to test your database driven applications. First, you may use the seeInDatabase helper to assert that data exists in the database matching a given set of criteria. For example, if you would like to verify that there is a record in the users table with the email value of sally@example.com, you can do the following:

public function testDatabase()
{
    // アプリケーションを呼び出す…

    $this->seeInDatabase('users', [
        'email' => 'sally@example.com'
    ]);
}

もちろん、seeInDatabaseメソッドやその他のヘルパは、利便性のために用意しています。PHPUnitの組み込みアサートメソッドは、テストで自由に使用できます。Of course, the seeInDatabase method and other helpers like it are for convenience. You are free to use any of PHPUnit's built-in assertion methods to supplement your tests.

各テスト後のデータベースリセットResetting The Database After Each Test

前のテストデータが、それに引き続くテストへ影響をあたえないように、各テストが終了するごとにデータベースをリセットするのは、時に便利です。It is often useful to reset your database after each test so that data from a previous test does not interfere with subsequent tests.

マイグレーションの使用Using Migrations

一つのアプローチは、それぞれのテストの後にデータベースをロールバックし、次のテストの前にマイグレーションする方法です。Laravelはこれを自動的に処理するために、シンプルなDatabaseMigrationsトレイトを用意しています。テストクラスでこのトレイトを使用するだけで、すべて処理されます。One approach to resetting the database state is to rollback the database after each test and migrate it before the next test. Laravel provides a simple DatabaseMigrations trait that will automatically handle this for you. Simply use the trait on your test class and everything will be handled for you:

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends TestCase
{
    use DatabaseMigrations;

    /**
     * 基本的な機能テストの例
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->visit('/')
             ->see('Laravel 5');
    }
}

トランザクションの使用Using Transactions

データベースをリセットするもう一つのアプローチは、各テストケースをデータベーストランザクションでラップしてしまうことです。Laravelはこれを自動的に処理する、便利なDatabaseTransactionsトレイトを用意してます。Another approach to resetting the database state is to wrap each test case in a database transaction. Again, Laravel provides a convenient DatabaseTransactions trait that will automatically handle this for you:

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends TestCase
{
    use DatabaseTransactions;

    /**
     * 基本的な機能テストの例
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->visit('/')
             ->see('Laravel 5');
    }
}

Note: note デフォルトでは、このトレイトは、トランザクション中のデフォルトデータベース接続をラップしているだけです。もし、アプリケーションで複数のデータベース接続を使用している場合は、テストクラスの$connectionsToTransactプロパティを定義する必要があります。このプロパティはトランザクションで実行する接続名の配列を指定します。{note} By default, this trait will only wrap the default database connection in a transaction. If your application is using multiple database connections, you should define a $connectionsToTransact property on your test class. This property should be an array of connection names to execute the transactions on.

ファクトリの記述Writing Factories

テスト時、何件かのレコードをデータベースに挿入する必要が起きることがあります。こうしたテストデータを作る時に、手動でそれぞれのカラムへ値を指定する代わりに、Laravelでは「ファクトリ」を使用しEloquentモデルの各属性にデフォルトを設定できます。手始めに、アプリケーションのdatabase/factories/ModelFactory.phpファイルを見てください。このファイルには最初からファクトリの定義が含まれています。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 default set of attributes for each of your Eloquent models[/docs/{{version}}/eloquent] using model factories. To get started, take a look at the database/factories/ModelFactory.php file in your application. Out of the box, this file contains one factory definition:

$factory->define(App\User::class, function (Faker\Generator $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});

ファクトリで定義しているクロージャの中から、モデルの全属性に対するデフォルトのテスト値を返しています。このクロージャはFaker PHPライブラリーのインスタンスを受け取っており、これはテストのための多用なランダムデータを生成するのに便利です。Within the Closure, which serves as the factory definition, you may return the default test values of all attributes on the model. The Closure will receive an instance of the Faker[https://github.com/fzaninotto/Faker] PHP library, which allows you to conveniently generate various kinds of random data for testing.

もちろん追加のファクトリをModelFactory.phpに自由に追加できます。系統立てるためには各モデルのファクトリーファイルを追加したほうが良いでしょう。たとえば、database/factoriesディレクトリの中へUserFactory.phpCommentFactory.phpファイルを作成します。 factoriesディレクトリ中のファイルは、自動的にLaravelにより読みこまれます。Of course, you are free to add your own additional factories to the ModelFactory.php file. You may also create additional factory files for each model for better organization. For example, you could create UserFactory.php and CommentFactory.php files within your database/factories directory. All of the files within the factories directory will automatically be loaded by Laravel.

ファクトリステートFactory States

ステートにより、どんな組み合わせのモデルファクトリに対しても、変更を取り消す定義を行うことができます。たとえば、Userモデルがデフォルトの属性値を変更する、delinquentステートを持っているとしましょう。stateメソッドを使い、状態の変更を定義できます。States allow you to define discrete modifications that can be applied to your model factories in any combination. For example, your User model might have a delinquent state that modifies one of its default attribute values. You may define your state transformations using the state method:

$factory->state(App\User::class, 'delinquent', function ($faker) {
    return [
        'account_status' => 'delinquent',
    ];
});

ファクトリの使用Using Factories

モデルの生成Creating Models

ファクトリを定義し終えたら、テストかデータベースのシーディング(初期値設定)ファイルの中で、グローバルなfactory関数を使用してモデルインスタンスを生成できます。では、モデル生成の例をいくつか見てみましょう。最初はmakeメソッドでモデルを生成し、データベースには保存しないでみましょう。Once you have defined your factories, you may use the global factory function in your tests or seed files to generate model instances. So, let's take a look at a few examples of creating models. First, we'll use the make method to create models but not save them to the database:

public function testDatabase()
{
    $user = factory(App\User::class)->make();

    // モデルをテストで使用…
}

さらにモデルのコレクションや指定したタイプのモデルも生成できます。You may also create a Collection of many models or create models of a given type:

// App\Userインスタンスを3つ生成
$users = factory(App\User::class, 'admin', 3)->make();

ステートの適用Applying States

また、任意の状態をモデルに適用することもできます。モデルに複数の状態変換を適用したい場合は、適用したい各状態の名前を指定する必要があります:You may also apply any of your states[#factory-states] to the models. If you would like to apply multiple state transformations to the models, you should specify the name of each state you would like to apply:

$users = factory(App\User::class, 5)->states('delinquent')->make();

$users = factory(App\User::class, 5)->states('premium', 'delinquent')->make();

属性のオーバーライドOverriding Attributes

モデルのデフォルト値をオーバーライドしたい場合は、makeメソッドに配列で値を渡してください。指定した値のみ置き換わり、残りの値はファクトリで指定したデフォルト値のまま残ります。If you would like to override some of the default values of your models, you may pass an array of values to the make method. Only the specified values will be replaced while the rest of the values remain set to their default values as specified by the factory:

$user = factory(App\User::class)->make([
    'name' => 'Abigail',
]);

モデルの保存Persisting Models

createメソッドはモデルインスタンスを生成するだけでなく、Eloquentのsaveメソッドを使用しデータベースへ保存します。The create method not only creates the model instances but also saves them to the database using Eloquent's save method:

public function testDatabase()
{
    // 一つのApp\Userインスタンスを作成
    $user = factory(App\User::class)->create();

    // 3つのApp\Userインスタンスを作成
    $users = factory(App\User::class, 3)->create();

    // モデルをテストで使用する…
}

createメソッドに配列で値を渡すことで、モデルの属性をオーバーライドできます。You may override attributes on the model by passing an array to the create method:

$user = factory(App\User::class)->create([
    'name' => 'Abigail',
]);

リレーションRelationships

以下の例では、生成したモデルにリレーションを付けています。複数モデルの生成にcreateメソッドを使用する場合、インスタンスのコレクションが返されます。そのため、コレクションで使用できるeachなどの便利な関数が利用できます。In this example, we'll attach a relation to some created models. When using the create method to create multiple models, an Eloquent collection instance[/docs/{{version}}/eloquent-collections] is returned, allowing you to use any of the convenient functions provided by the collection, such as each:

$users = factory(App\User::class, 3)
           ->create()
           ->each(function ($u) {
                $u->posts()->save(factory(App\Post::class)->make());
            });

リレーションと属性クロージャRelations & Attribute Closures

クロージャ属性をファクトリ定義の中で使い、モデルとのリレーションを追加することもできます。たとえば、Postを作成する時に、新しいUserインスタンスも作成したい場合は、以下のようになります。You may also attach relationships to models using Closure attributes in your factory definitions. For example, if you would like to create a new User instance when creating a Post, you may do the following:

$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph,
        'user_id' => function () {
            return factory(App\User::class)->create()->id;
        }
    ];
});

さらに、クロージャは評価済みのファクトリーの配列を受け取ることもできます。These Closures also receive the evaluated attribute array of the factory that contains them:

$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph,
        'user_id' => function () {
            return factory(App\User::class)->create()->id;
        },
        'user_type' => function (array $post) {
            return App\User::find($post['user_id'])->type;
        }
    ];
});

章選択

開発環境
ビューとテンプレート
公式パッケージ

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
OS表示
全OS表示
macOSのみ表示
windowsのみ表示
linuxのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作