【Laravel 5.4】Laravel Duskによるブラウザテストの作成方法

# :bell:この記事について

* Laravel5.4 から導入された[Laravel Dusk](https://laravel.com/docs/5.4/dusk)というE2Eテストツールを使ったチュートリアルを実際にやってみたので、その備忘録です
* この記事は、下記のLaravelの公式ドキュメントを参考にしています
    * https://laravel.com/docs/5.4/dusk

# :pencil: Laravel 5.4で開発する準備

Laravel5.4
https://github.com/laravel/laravel

上記から`git pull`するなり、ZIPファイルを落とすなりしてローカルにコードを持ってきます。
その後、`composer update`を実行します。

```console
$ composer update
```

.envファイルも作成。

```console
$ cp .env.sample .env
```

# :closed_lock_with_key:ログイン画面の実装

Laravelにはすでに認証に必要な機能がフレームワークに盛り込んであります。そのため、簡単な手順でログイン機能の実装を自動的に構築することができます。

まず、下記のコマンドを実行します。

```console
$ php artisan make:auth
Authentication scaffolding generated successfully.
```

すると、認証に必要なログイン画面やユーザ作成画面等のルート定義やビューが自動的に設定されます。
あとはアプリに必要なデータベースを用意し、マイグレーションファイルを実行することで、ログインに必要なテーブルを生成します。

```console
$ php artisan migrate
```

そして、`php artisan serve`等でアプリを起動し、
http://localhost:8000/register
にアクセスすると、下記のようなユーザ作成画面が表示されるはずです。

![スクリーンショット 2016-12-10 11.45.11.png](https://qiita-image-store.s3.amazonaws.com/0/42852/4828ede0-3fb4-cafc-51b6-da5a9e5382bc.png)


# :desktop:Laravel Duskによるブラウザテスト

Laravel5.4 から [Laravel Dusk](https://laravel.com/docs/5.4/dusk)というJavaScriptを用いたアプリに対応しているE2Eテストツールが導入されています。

それまでLaravelに含まれていたBrowserKitでは、JSとAjaxを使用したページの動作テストはできていなかったのですが、このLaravel Duskではそれを可能にしています。

## Laravel Duskのインストール

composer.jsonに`"laravel/dusk"`を追加して、再度`composer update`を実行して、インストールします。


```json:composer.json
    "require": {
        "php": ">=5.6.4",
        "laravel/framework": "5.4.*",
        "laravel/tinker": "~1.0",
        "laravel/dusk": "~1.0"
    },
```

## ServiceProviderにDuskを登録する

AppServiceProviderを下記のように編集します。

```php:app/Providers/AppServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Laravel\Dusk\DuskServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        if ($this->app->environment('local', 'testing')) {
            $this->app->register(DuskServiceProvider::class);
        }
    }
}
```


## サンプルテストの実行

これでLaravel Duskを使う準備は整いました。
下記のコマンドを実行してみましょう。

```console
$ php artisan dusk:install
Dusk scaffolding installed successfully.
```

すると、`tests`ディレクトリにサンプルテストが生成されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/42852/a6a5e636-b0bb-ba6c-c047-08a1f3956a72.png)

試しにこのサンプルテストを実行……の前に、`.env`ファイルの`APP_URL`に、テスト対象のアプリのURLを定義するようにしましょう。

```.env
APP_URL=http://localhost:8000
```

サンプルテストの実行は、下記のコマンドを叩くだけで実行されます。
コマンドを叩くと、Chromeが起動し、なにやら画面が遷移するのが一瞬確認できると思います。
ターミナルを確認してみると、下記のようなログが表示されていました。テストが正常に通ったようですね :relaxed: 

```console
$ php artisan dusk
PHPUnit 5.7.9 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 2.77 seconds, Memory: 10.00MB

OK (1 test, 1 assertion)
```

## ログインフォームのテストを作成

![image](https://qiita-image-store.s3.amazonaws.com/0/42852/956be26b-685e-91bd-accd-26df9fb8a56a.png)

まずは、アプリケーションにログインすることができるテストを作成します。

Duskのテストケースを作成するには、下記のコマンドを実行します。
すると、`tests/Browser/LoginTest.php`が生成されます。

```console
$ php artisan dusk:make LoginTest
```

生成されるのはサンプルのテストケースになっているので、中身を書き換えていきます。
今回は、ログインページに遷移し、メールアドレスなどの情報をフォームに入力したあと、「Login」ボタンをクリックする、というテストケースになります。
モデルファクトリーでユーザを生成し、browseメソッドでbrowserインスタンスを生成しています。

```php:tests/Browser/LoginTest.php
<?php

namespace Tests\Browser;

use App\User;
use Tests\DuskTestCase;
use Laravel\Dusk\Chrome;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class LoginTest extends DuskTestCase
{
    use DatabaseMigrations;

    /**
     * A basic browser test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $user = factory(User::class)->create([
            'email' => 'taylor@laravel.com',
        ]);

        $this->browse(function ($browser) use ($user) {
            $browser->visit('/login')
                    ->type('email', $user->email)
                    ->type('password', 'secret')
                    ->press('Login')
                    ->assertPathIs('/home');
        });
    }
}
```

例えば、`type`もしくは`name`属性が`email`となっているフォームに値を入力する際は、下記のように記述することで表現できます。

```php
$browser->type('email', 'taylor@laravel.com');
```

他にもチェックボックスのクリックや、ファイルの添付、マウスオーバーなどの操作も設定することができますが、詳しくは公式のドキュメントを参考にして頂ければと思います :bow:

https://laravel.com/docs/5.4/dusk

## 作成したテストの実行

それでは、先程と同じようにコマンドを実行して、テストが通るか確認してみましょう。
コマンドを実行してみると、ブラウザが起動し、フォーム画面からIDとパスワードが自動的に入力されていることを確認できるかと思います。

```console
$ php artisan dusk
PHPUnit 5.7.9 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 8.01 seconds, Memory: 14.00MB

OK (2 tests, 2 assertions)
```