Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
57
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

【Laravel】PHPUnitテスト用にDBを設定してデフォルトのDBを汚さなくする

テスト用にDBを用意してテストを実行する

テスト実行するたびにDBが消えたりテストデータが登録されたりするのは鬱陶しいので
PHPUnit用にDBを用意してテスト実行時はそのDBを使用するようにしてみます

こちらも参考にしてください
【Laravel】PHPUnitテスト用にSQLiteをDBに設定した際に気を付けるべきマイグレーションの記述と解決方法

実装例

configディレクトリ以下のdatabase.phpにtesting用の設定を追加

laravel\config\database.php
<?php

    /*
    |--------------------------------------------------------------------------
    | Database Connections
    |--------------------------------------------------------------------------
    |
    | Here are each of the database connections setup for your application.
    | Of course, examples of configuring each database platform that is
    | supported by Laravel is shown below to make development simple.
    |
    |
    | All database work in Laravel is done through the PHP PDO facilities
    | so make sure you have the driver for your particular database of
    | choice installed on your machine before you begin development.
    |
    */

    'connections' => [

        // -- 省略 -- //

        // 以下を追加する
+       'testing' => [
+           'driver'   => 'sqlite',
+           'database' => ':memory:', // SQLiteのインメモリ機能を使用
+           'prefix'   => '',
+           'options'  => [
+               // テストデータの永続化
+               PDO::ATTR_PERSISTENT => false,
+           ],
+       ],

    ],

SQLiteのインメモリ機能とは以下のような性質をもっているので、ユニットテスト向きっぽいです

When this is done, no disk file is opened. Instead, a new database is created purely in memory. The database ceases to exist as soon as the database connection is closed. Every :memory: database is distinct from every other. So, opening two database connections each with the filename ":memory:" will create two independent in-memory databases.

以下Google翻訳

これが行われると、ディスクファイルは開かれません。代わりに、新しいデータベースが純粋にメモリ内に作成されます。データベース接続が閉じられるとすぐにデータベースは存在しなくなります。 Every:memory:databaseは他のものとは異なります。そのため、それぞれ ":memory:"というファイル名で2つのデータベース接続を開くと、2つの独立したインメモリデータベースが作成されます。

SQLiteの「In-Memory Databases」機能についての詳細は以下を参照
In-Memory Databases

phpunit.xmlにも同様testing用の設定を追加

laravel/phpunit.xml
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
+       <env name="DB_CONNECTION" value="testing"/>
    </php>
</phpunit>

※5.8系では以下のように記述

laravel/phpunit.xml
    <php>
        <server name="APP_ENV" value="testing"/>
        <server name="BCRYPT_ROUNDS" value="4"/>
        <server name="CACHE_DRIVER" value="array"/>
        <server name="MAIL_DRIVER" value="array"/>
        <server name="QUEUE_CONNECTION" value="sync"/>
        <server name="SESSION_DRIVER" value="array"/>
+       <server name="DB_CONNECTION" value="testing"/>
    </php>

テストコード実装例

UserTest.php
<?php

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use App\User;

class UserTest extends TestCase
{
    use RefreshDatabase;

    private $attributes;

    public function setUp()
    {
        parent::setUp();

        $this->attributes = [
            'name'     => 'テスト太郎',
            'mail'     => 'hoge@example.com',
            'password' => bcrypt('test'),
        ];
    }

    public function test_登録できる()
    {
        User::create($this->attributes);
        $this->assertDatabaseHas('users', $this->attributes);
    }

}

これで実DBを汚さず遠慮なくテストを実行できるようになりました

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
57
Help us understand the problem. What are the problem?