TokyoFacebookTwitterHatenaPocket複雑なシンプルページアプリケーション(SPA)こそテストが大事ですが、手作業でやるには大変。そこで、Laravelのテストライブラリー「Dusk」を使ってみましょう。JavaScriptアプリケーション、特にシングルページアプリケーションにおいてエンドツーエンドテストは常に課題です。Laravelは最近、その課題の打開案となる新しいテストライブラリー、Duskの5.4バージョンをリリースしました。今回のDuskのリリースで、Laravelはユーザーにブラウザーテスト用の共通APIを提供するようになりました。デフォルトでChromeDriverが付属し、ほかのブラウザーのサポートが必要な場合はSeleniumを使用できます。ニーズに応えるために、今後もこの共通テストAPIをサポートされる予定です。5.4アプリケーションを紹介します。laravel/dusk上の方法でComposerを経由して最新の安定バージョンのパッケージをインストールできます。次に、アプリケーション内でDuskServiceProviderを登録する必要があります。いくつかの方法があります。アプローチ1config/app.phpファイルにproviders配列を含められます。...App\Providers\RouteServiceProvider::class,Laravel\Dusk\DuskServiceProvider::class,...このアプローチの問題点は、すべての環境でDuskServiceProviderがアプリケーションに登録されてしまうことです。本番環境でDuskを使えるようにする必要はありません。次のアプローチで、この現象を回避します。アプローチ2特定の環境のAppServiceProviderクラスにDuskServiceProviderを登録します。}}下のようにして、インストールプロセスを完了します。dusk:installこのコマンドでDuskは基本的なクラスとディレクトリを構築します。testsディレクトリを開くと、Duskのテストに必要なファイルが入ったBrowserディレクトリが確認できます。最初のテスト最初に、Laravelに用意されている認証機能を使用して認証のワークフローを作ります。make:auth最初のDuskテストを作成します。LoginTest上のコマンドでBrowserディレクトリにLoginTestクラスを作成します。}}上のテストケースでは、ユーザーがシステムに正常にログインし、ホームページでウェルカムメッセージを確認できるかどうかをテストしています。注意:このテストは、データベースに実際のユーザーが存在する必要があります。デモンストレーションでは、すでにデータベースに認証情報を持つユーザーを作成しています。Duskテストを実行します。duskデータベースに正しい認証情報を持つユーザーが存在する場合、次の出力が表示されます。assertions)テストに失敗した場合テストに失敗するとPHPUnitはエラーをスローします。なにが悪かったのかを理解する必要があるからです。Duskには、このユースケースに対応するための特徴的なオプションがいくつかあります。テストを意図的に失敗するために修正します。});}上のテストケースでは、データベースに存在しないユーザーでログインしようとしています。Duskテストを実行すると、次のような起こります。注意深く見ていると、テストが失敗する直前にブラウザーが開くのが分かります。Duskでは、エラーが発生したページのスクリーンショットを取得し、自動的にgit-ignoredでscreenshotsディレクトリに保存します。エラー発生時のスクリーンショットを保存することでテストが失敗する理由が視覚的に分かります。例では、認証情報がデータベースのレコードと一致していないことが確認できます。Duskを使えば、視覚的なフィードバックによって問題をすばやく特定できるようになります。AJAXコールのテストDuskは、最新のJavaScriptアプリケーションのエンドツーエンドブラウザーテストを目的としています。このようなアプリケーションでは、典型的なユースケースとして、AJAXリクエストのレスポンスが用意されているケースがあります。Task機能を使ってテストします。Githubからクローンしてフォローしてください。AJAXリクエストを使って新しいタスクを作成したあと、タスクリストページにリダイレクトさせます。これは完璧なテストのユースケースです。CreateTaskTest上のコマンドでBrowserディレクトリにCreateTaskTestクラスが作成されます。次にテストを作成します。}}上のテストでは、AJAXフォームを使って次のような新しいテストを追加しています。タイトルを入力するタスク追加ボタンをクリックする5秒間待つtasksページへリダイレクトするDuskテストを実行し、結果を確認します。見ての通り、テストは成功しました。上のフローをテストするため、DuskのAPIメソッドwaitUntilMissingも使用できます。}}APIで利用可能なWait要素については、公式ドキュメントを参照してください。今度の例では、アプリケーションにメニューアイテムがあり、その中のサポートEメールリンクをクリックすると、サポートメールを送信するためのフォームをポップアップで表示します。以下のシナリオをテストするテストケースを作成します。ログインするサポートEメールが表示されるサポートEメールをクリックするモーダルが開き、テキストボックスにユーザーのEメールIDが表示される上のgifアニメーションでは、マウスを使用してUIを操作し、モーダルを開いています。Duskのテストケースで上のフローを再作成します。最初に、新しいテストクラスを作成します。SupportEmailsTest次にテストを書きます。}}最後に、実行します。tests/Browser/SupportEmailsTest.phpテストが成功したことが分かります。assertion)そのほかの利用可能なアサーションについては、公式ドキュメントを参照してください。ページDuskにはページという概念があります。再利用可能なテストクラスで、非常に使いでがあります。ページを使用してCreateTaskTestをリファクタリングします。最初に新しいページを作成します。CreateTaskPage上のコマンドでPagesディレクトリに新しいクラスが作成されます。Taskテストケースを最適に修正します。'/tasks/create';}urlメソッドはページのURLを定義します。このページが呼び出されるたびにDuskによって定義したURLに遷移されます。$browser->assertPathIs($this->url());}assertはこのページのアサーションを定義します。CreateTaskPageが呼ばれるたびにassertメソッドで定義されたすべてのアサーションが実行されます。上の例ではシンプルに、アクティブなページのURLが適切であると定義しています。];}elementsメソッドは、事前にセレクタを定義できます。セレクタに読みやすい名前を付けると、異なるテストケースで再利用できます。Taskボタンのセレクタを定義しました。CreateTaskTestクラスを修正し、セレクタを使用します。}}CreateTaskPageを使ってクラスを修正しました。一度、テストして成功するか確認します。assertions)成功しました!特定のページで、再利用可能なアクションを実行するカスタムメソッドも定義できます。詳しくは公式ドキュメントを参照してください。Duskを取り上げました。使い始めるにあたって必要なオプションを例を使ってを解説し、ほかに使用可能なオプションについての概要も紹介しました。Rafieが査読を担当しています。最高のコンテンツに仕上げるために尽力してくれたSitePointの査読担当者のみなさんに感謝します。PHPで複雑な問題に挑戦することが大好きで、サーバーだけでなく、水泳やブログも大好きです。