LaravelのDocker環境開発で2つDB作ってWeb用と単体テスト用に分けといて開発中はコマンド1つで両方リセットしとく。

- DBをWeb用と単体テスト用の2つ用意する。
- 開発中はDB定義更新したらリセットして最新反映してWeb用のみシーダーを実行したい。

## Dockerでテスト用のDBを作成する

### テストDBを作成するSQLファイルを設置する

- ./mysql/init/createdb.sql
- test_databaseという名前のDBを作成

```mysql/init/createdb.sql
CREATE DATABASE IF NOT EXISTS `test_database` COLLATE 'utf8_unicode_ci' ;
GRANT ALL ON `test_database`.* TO `docker` ;
```

- dbのvolumesで./mysql/initディレクトリにdocker-entrypoint-initdb.dを割り当てる

```docker-compose.yml
  ...省略
  db:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: web_database
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
    volumes:
      - db-data:/var/lib/mysql
      - ./mysql/init:/docker-entrypoint-initdb.d <-ここです。
    networks:
      - dockernetworks
networks:
  docker-net:
volumes:
  db-data:
```

- ボリュームを消して反映させる

```
docker-compose down
docker volume rm hoge_db-data
docker-compose up
```

## 単体テスト用DBの設定

### .env.testing作成

```.env.testing
APP_ENV=testing
APP_KEY=xxxxxxxxxx
APP_DEBUG=true

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=test_database
DB_USERNAME=docker
DB_PASSWORD=docker
```

### 単体テスト実行

```
% docker-compose exec app php vendor/bin/phpunit
```


### 「test」DBの設定

- コネクションのmysqlをコピーしてmysql_testing作成、databaseを「test」にする

```config/database.php
        'mysql' => [...省略...],
        'mysql_testing' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => 'test',
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
```

## 開発中のDB更新

### DBリフレッシュコマンド作成

```
% docker-compose exec app php artisan make:command DBRefreshCommand
```

```app/Console/Commands/DBRefreshCommand.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class DBRefreshCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'db:refresh';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'DB Refresh';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        if (env('APP_ENV') === 'local' && env('APP_DEBUG') === true) {
            $this->info('Refresh DB [Web用]');
            $this->call('migrate:refresh', ['--seed' => 1]);

            $this->info('Refresh DB [単体テスト用]');
            $this->call('migrate:refresh', ['--database' => 'mysql_testing']);
        } else {
            $this->error('開発のみ使用のコマンドです。');
        }
    }
}

```


```app/Console/Kernel.php
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        App\Console\Commands\DBRefreshCommand::class,
    ];
```

### リフレッシュコマンド実行

```php

% docker-compose exec app php artisan db:refresh
Refresh DB [Web用]
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back:  2014_10_12_100000_create_password_resets_table (0.06 seconds)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back:  2014_10_12_000000_create_users_table (0.01 seconds)
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.05 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.04 seconds)
Database seeding completed successfully.
Refresh DB [単体テスト用]
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back:  2014_10_12_100000_create_password_resets_table (0.02 seconds)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back:  2014_10_12_000000_create_users_table (0.01 seconds)
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.03 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.03 seconds)

```