tanaka's Programming Memo

プログラミングについてのメモ。

Laravel5.3とVue.jsを組み合わせたページをCodeceptionでテストする

LaravelのPHPのみのページのテストは、CodeceptionのFunctionalテストで問題なく動きますが、Vue.jsを利用したようなJavaScriptを使ったページは、Functionalテストでは完全にテストできないようです。そのような場合は、実際のWebブラウザー上でテストするAcceptanceテストを利用します。

Seleniumを利用したり、テスト環境を利用する方法で手間取ったので、動作に必要だった項目をまとめます。


PhpBrowserのテストの欠点

03-AcceptanceTests - Codeception - Documentationによると、以下のような欠点があります。

  • you can click only on links with valid urls or form submit buttons
    • クリックできるのは、有効なURLやフォームのSubmitボタンのみ
  • you can’t fill fields that are not inside a form
    • フォーム内のフィールドに入力することができない
  • you can’t work with JavaScript interactions: modal windows, datepickers, etc.
    • モーダルウィンドウやdate pickerをはじめとするJavaScriptの動作が利用できない

Vue.jsはJavaScriptですので、PhpBrowserによるテストはできません。WebDriverを使う必要があるということです。


CodeceptionとWebDriverの動作環境は別

Codeceptionのテストコードもサービスのサーバ側のPHPプログラムも同じPHPプログラムですが、Acceptanceテストではテストコードとサーバ側プログラムは動作環境が別になります。そのため、以下の2点に注意が必要です。

  • .env.testingファイルは、CodeceptionとWebDriverの双方に読み込ませる設定が必要
  • Acceptanceテストコードから、LaravelやSentinelのヘルパー関数を使ってWeb側のアプリの情報を読み取ることはできない

Functionalテストでは、テストと実行環境が同じなので上記のいずれも問題が起きません。Acceptanceテストでの注意点です。


.envと.env.testingの読み分け

Codeception用の設定

Acceptanceテスト用の設定は以下のようにします。Chromeでテストする例です。

  • tests/acceptance.suite.yml をエディターで開く
  • 以下の内容にする
class_name: AcceptanceTester
modules:
    enabled:
        - WebDriver:
            url: http://localhost:8000
            browser: chrome
        - Laravel5:
            environment_file: .env.testing
            part: ORM
            cleanup: false
        - \Helper\Acceptance

以上で、Acceptanceテストを実行すると、Chromeが起動して、 http://localhost:8000 をベースのURLとしてテストが始まります。テストコードからLaravelのfacadeやヘルパー関数が呼び出せます。

Webブラウザー側の設定

acceptance.suite.yml の設定は、Codeceptionで動作するテスト用のものであり、Webブラウザー側とは別です。Webブラウザー側でも .env.testing を読み込ませるには、以下でサービスを起動します。

php artisan serve --env=testing

--env=tesging オプションにより、 .env.testing を環境ファイルとして読み込むようになります(Configuration - Laravel - The PHP Framework For Web Artisans)。

以上で、テスト環境と実行環境のどちらも .env.testing を読み込むようになります。


データベースの初期化

Acceptanceテストでは、トランザクションがテスト側から管理できないため、テスト中に登録したデータの削除ができません(Codeception for Laravel)。そこで、実行前に tests/acceptance/TestCest.php などの _before メソッドで以下を実行して、データベースを初期化すると良いでしょう。

    public function _before(AcceptanceTester $I)
    {
        // データベースを削除
        Artisan::call('migrate:refresh');
    }



テスト時に必要な準備

テストを実行するには、以下を準備しておく必要があります。

  • Selenium Standalone Server のjarファイルをダウンロードして起動(PhatomJSでも良いようだが、うまく動かなかったのでSeleniumを利用)
    • http://www.seleniumhq.org/download/ から、最新の Selenium Standalone Server をダウンロード
    • 以下で起動(3.0.1の部分は、実際にダウンロードしたバージョン番号に置き換える)
java -jar selenium-server-standalone-3.0.1.jar
  • サービスを起動
php artisan serve --env=testing
  • データベースサーバーを起動。mysqlの場合は以下
sudo mysqld_safe

以上が完了したら、以下でテストを実行できる。

composer exec codecept run



Codeceptionで利用できるメソッド

WebDriverのものが利用できます。

WebDriver - Codeception - Documentation

特に、以下のものが有用です。

  • waitForText()
    • テキストが表示されるのを待つ
  • waitForElementVisible()
    • 要素が表示されるのを待つ
  • acceptPopup()
    • ポップアップのOKなどを押す
  • cancelPopup()
    • ポップアップをキャンセルする
  • seeInPopup()
    • ポップアップに指定の文字が表示されているかを確認
  • typeInPopup()
    • ポップアップに文字を入力



まとめ

  • JavaScriptのテストには、WebDriverを使ったAcceptanceテストが必要
  • 環境の設定は、Codeception用のものと、Webブラウザー用のものをそれぞれやる必要がある
  • データベースはリセットされないので、必要に応じて自分でクリアする
  • Acceptanceテストには、SeleniumかPhantomJSが必要(PhantomJSで日本語をチェックするには環境設定が必要かもしれない。Seleniumの方が簡単に動く)

おおよそ、以上で動くと思います。


参考URL