Laravel Dusk + AngularJSで自動テスト


きっかけ

現在フロントをAngularJS、サーバサイドをLaravel開発しています。
サーバサイドには自動テストを導入していますが、画面のテストは未導入だったので、試してみました。
私はサーバサイドを作っており、AngularJSを全く理解していないので、ご了承ください。

環境

Laravel5.6 + PHP7.2
AngularJS
Vagrant(AmazonLinux2)

ログインテストを作る

インストール

インストールは下記を参照しました。
https://laravel.com/docs/5.6/dusk#installation

AppServiceProviderに追記

AppServiceProvider.php
class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     * @see \Clockwork\DataSource\EloquentDataSource::createRunnableQuery()
     * @see LoggerCustomize
     */
    public function boot()
    {
        // 'local' または 'develop' の場合
        if (app()->isLocal() || app()->environment() == 'develop') {
            $this->app->register(DuskServiceProvider::class);
        }
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

bootメソッドに$this->app->register(DuskServiceProvider::class);を追記しないとphp artisan duskが使えませんでした。
laravel duskは本番環境では使用しないため、環境がlocalまたはdevelopの場合のみ適応されるようにしています。
app/configapp.phpに記載しても動くと思いますが、本番環境では動かさないようにするため、AppServiceProvider.phpに記載しています。

テストを記述する

下記のコマンドを叩いてテストを作成します。

 php artisan dusk:make LoginTest

はじめにLoginTest.phpには下記のテンプレが入っています。

LoginTest.php
<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class LoginTest extends DuskTestCase
{
    /**
     * A basic browser test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/')
                    ->assertSee('Laravel');
        });
    }
}

こんな感じで書き換えてみます。

LoginTest.php
<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class LoginTest extends DuskTestCase
{
    /**
     * A basic browser test example.
     *
     * @return void
     */
    public function testLogin()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/login')
                ->pause(5000)
                ->assertSee('ユーザーID')
                ->assertSee('パスワード')
                ->screenshot('login_1')
                ->type('input.ss-input[type="text"]', 'ユーザー名')
                ->type('input.ss-input[type="password"]', 'パスワード')
                ->press('ログイン')
                ->pause(5000)
                ->assertSee('ダッシュボード')
                ->screenshot('login_2');
        });
    }
}

typeの第一引数には入力フィールド、selectorを指定できます。

valueというメソッドでvalueを直接入れることもできますが、AngularJSで制御している部分に引っかかってログインできませんでした。
typeを使うと実際にキーボードからタイピングしているような動きをするらしく、うまくいきました。

pause(5000)は画面が表示されるまで待つために入れています。
このselectorが出るまで待つという方法もあります。(waitForメソッド)

やってみて

便利ですね。AngularJSだけでなく、何で書かれていてもテストできるみたいなので、レガシーなwebアプリでも使えそうです。
画面もちゃんとテストコードを書いて、テスト自動化できたらいいなと思っています。
laradockではまだうまく言っていないので、次はlaradockで動かしてみたいなと思っています。

コメント、編集リクエストいただけると嬉しいです。