LoginSignup
3
3

More than 5 years have passed since last update.

Laravel DuskをWerckerで実行する

Last updated at Posted at 2017-02-19

2018-04-12 追記

出来る限りシンプルな構成で Laravel Dusk x Wercker x Headless Chrome のサンプルを新たに作ってみました。

Dockerイメージ

Docker Hub

GitHub

Laravel Dusk サンプル

Wercker実行結果

尚、以前のWercker実行結果は誤って削除してしまいました orz

概要

Laravel DuskをWerckerで動かすためのDockerイメージを作成しました。このイメージはDocker Hubで公開してあります。

Werckerで複雑な設定無しに実行できることを意識したので、必要なものが一式揃っているDockerイメージです。主に次の通りです。(シンプルな設定を保ちつつ合理的に分割できるならそうしたい。。。)

  • PHP 7.1.2
  • PHP-FPM
  • Nginx
  • MariaDB
  • webdriver-manager (for Selenium Server)
  • PhantomJS
  • Supervisor
  • Capistrano

備忘録として、具体的な設定を書いたサンプルプロジェクトもGitHubに置いてあります。
https://github.com/mamor/dusk-on-wercker-example

この記事では、上記のサンプルプロジェクトを用いた実行方法と、躓いたポイント等を説明します。

実行方法

ダウンロード

$ git clone https://github.com/mamor/dusk-on-wercker-example.git
$ cd dusk-on-wercker-example/
$ yarn install # or "npm install"

ローカルでの実行方法

docker-composeを用います。

$ docker-compose run --rm testing bash -i -c "gulp --gulpfile=/var/app/gulpfile.js ci:testing:all"

これでdusk(と、ついでにphpunit)が実行できます。"ci:testing:all"の箇所を"ci:testing:phpunit"または"ci:testing:dusk"にすると、それぞれ単独でも実行できます。gulpを用いている理由は、phpunitとduskを並列で実行するためです。

docker-compose.ymlは次の通りです。
https://github.com/mamor/dusk-on-wercker-example/blob/master/docker-compose.yml

# PHPUnit
#   docker-compose run --rm testing bash -i -c "gulp --gulpfile=/var/app/gulpfile.js ci:testing:phpunit"
# Laravel Dusk
#   docker-compose run --rm testing bash -i -c "gulp --gulpfile=/var/app/gulpfile.js ci:testing:dusk"
# Both
#   docker-compose run --rm testing bash -i -c "gulp --gulpfile=/var/app/gulpfile.js ci:testing:all"

version: "2"
services:
  testing:
    image: madworks/php-ci
    command: tail -f /dev/null
    volumes:
      - ~/.composer/cache:/root/.composer/cache
      - ./:/var/app
      - .env.ci.app:/var/app/.env
      - /var/app/vendor

Werckerでの実行方法

予め、Wercker側で"build"と"deploy"という名前のpipelineを用意します。"build"は最初からあるので、実質的には"deploy"を新規作成するだけでした。また、workflowで"build"の成功時に"deploy"を実行するように設定しておきます。

wercker.ymlは次の通りです。
https://github.com/mamor/dusk-on-wercker-example/blob/master/wercker.yml

box: madworks/php-ci
build:
  steps:
    - script:
      name: build
      code: |
        yarn config set cache-folder ${WERCKER_CACHE_DIR}/yarn
        source /root/.phpbrew/bashrc
        cp -r ./ /var/app
        cp .env.ci.app /var/app/.env
        yarn install --prefer-offline --production
        gulp ci:testing:all

deploy:
  steps:
    - script:
      name: deploy
      code: |
        which cap

"ci:testing:all"の箇所は、docker-compose.ymlと同様です。"deploy"の内容は、capコマンドのパスを出力するだけになっています。実際にはCapistranoの設定や実行コマンドを書く想定です。もちろん、Deployerでも構いません。

実行結果は次の通りです。

以上が、実行方法です。ローカルとWerckerとで異なるのは、ファイルの設置方法だけで、後はgulpで共通化しています。次に、前述したgulpのタスク"ci:testing:all"の流れを説明します。細かなタスクの内容は、ソースをご覧下さい。

gulp ci:testing:all

gulp.task('ci:testing:all', (callback) => {
  runSequence(
    ['ci:supervisord', 'ci:copy'],     // 1
    ['ci:php'],                        // 2
    ['ci:mysql'],                      // 3
    ['ci:migrate'],                    // 4
    ['ci:run:dusk', 'ci:run:phpunit'], // 5
    callback);
});
  1. "ci:supervisord"でwebdriver-manager,nginx,php-fpm,mariadbを起動。"ci:copy"でduskが実行される側(nginx配下 = /var/www)のファイルを配置
  2. "ci:php"でduskを実行する側(/var/app)と実行される側(/var/www)の準備
  3. "ci:mysql"でデータベースの準備
  4. "ci:migrate"でマイグレーションを実行
  5. "ci:run:dusk"でduskを実行。"ci:run:phpunit"でphpunitを実行

となります。"/var/app"はdev用ライブラリ込みでcomposer install、"/var/www"は--no-devでcomposer installしています。また、このテストではDBを用いていませんが、疎通確認を兼ねてマイグレーションを実行しています。gulpを使うと並列で良い処理、直列であるべき処理の管理が楽ですね。

躓いたポイントや問題点

"TTY mode requires /dev/tty to be read/writable."エラー

追記: この問題は https://github.com/laravel/dusk/pull/226 で解決されました。

dusk実行時に、次と同じ内容のエラーが出ました。
https://laracasts.com/discuss/channels/testing/tty-mode-requires-devtty-to-be-writable

次のissuesを真似して"script"コマンドにすると、確かに実行はできるのですが、テスト失敗時もWerckerのbuildが継続してしまいました。終了コードが伝播されない感じでしょうか。
https://github.com/wercker/wercker/issues/95

この問題を解決するために、とりあえず"DuskCommand"を拡張しました。実は、前述のサンプルプロジェクトでは、duskを"php artisan app:dusk"として実行しています。
https://github.com/mamor/dusk-on-wercker-example/commit/ac0666fa7d470f08fbf02fc162b4415f583ea8ff#diff-2188cf5d4ddf4333bd48355426788696

やりたかったことは"setTty(false)"です。オリジナルでは、Windowsの場合にfalse、それ以外の場合にtrueとなっていて、まだ、その意図をよく理解できていません。一応、PRは出しておきました。 https://github.com/laravel/dusk/pull/136

そして、--no-dev時にduskをインストールしたくなかったので"app/Console/Kernel.php"におけるコマンド登録が次のようになっています。
https://github.com/mamor/dusk-on-wercker-example/commit/ac0666fa7d470f08fbf02fc162b4415f583ea8ff#diff-dc9276478c4a31a6639a7c904c29ac04

ChromeとPhantomJSの切り分け

実用を考えると、普段はChromeで動かし、CI環境等ではPhantomJSで動かしたかったので、DuskTestCase.phpを次のようにしました。
https://github.com/mamor/dusk-on-wercker-example/commit/ac0666fa7d470f08fbf02fc162b4415f583ea8ff#diff-3d758536f1d68e823ad5ec04b8921a1e

以上となります。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3