cover

骨折しました。@kyo_agoです。

今日はTravisCI上で実ブラウザ環境のテストを行う方法を紹介したいと思います。

弊社ではこれまで実ブラウザ環境のテストではTravisCIからProtractorを使ってSauceLabsへ接続してテストを行っていました。

しかし、これには以下のような問題があったため、ProtractorとSauceLabsを使用しない構成へ移行しました。

テストが高頻度で失敗する

テストに影響しない部分の修正ですらテストが失敗し、コードの修正よりテストを通すほうが難しい状況になっていました。
(これは社内では「e2eガチャ」と呼ばれ、レビュー依頼のコメントには「e2eガチャ 1/5」と成功率が書かれていました。ちなみに「1/5」はわりといい確率です。悪い時は「1/12」くらいになります)

遅い

SauceLabsへの接続時間、WebDriver経由のテスト実行などはかなり重い処理になり、これだけで数分かかる状態でした。

また、それぞれのテスト実行が1テストごとに数秒かかるため、今後このままテストを追加していくと単純にテスト実行時間が伸びていく懸念がありました。。
(1テストに数秒かかるのはexecuteAsyncScriptやexecuteScriptを使用しているのが原因のようだったのですが、書き換えが困難だったため対応を検討していました)

デバッグが難しい

Protractorが内部で使用しているWebDriverはChromeのDebuggerと共存することができないため、Protractorを実行中にChromeのDevToolsを開くことができません。

Protractorはコード上に記述したconsole.logの出力をターミナルへ転送してくれますが、インタラクティブな操作ができないため通常のDevToolsと比較するとデバッグが非常に困難です。

依存サービスが増える

単純に依存サービスが増えるとサービスダウンのリスクも増えます。 実際SauceLabsもサービスダウンすることがあり、その間はテストの実行ができなくなりました。

また、サービスはダウンしていなくてもTravisCIからSauceLabsへの接続に失敗することもあり、その場合もテストの実行ができません。


上記のような問題から弊社ではTravisCI上でFirefoxを起動してkarmaを使う構成へ移行しました。

これにより、外部サービスへの依存とWebDriverが不要になり、テストの実行が安定かつ高速になりました。

また、テスト実行中もDevToolsが起動できるためデバッグも非常に容易です。

ただ、これには以下のようなデメリットもあります。

録画、実行ログがない

SauceLabsではテスト実行中のブラウザ動作、WebDriverの通信ログを保存していますが、TravisCI状のみで完結する場合そういったサポートは受けられません。

クロスブラウザの検証が困難

後述しますが、TravisCI上のChromeはバージョンが古く、テストの実行環境として使用するには向きません。

また、当然Safari、IE、Edge、スマートフォンブラウザ環境も存在しないため、クロスブラウザテストを行う必要がある場合SauceLabsが必要になります。

実行方法が特殊

Protractorではテスト環境のURLを指定すれば、そのまま環境を読み込んでテストを実行できます。

しかし、karmaはWebDriverを使用していないため読み込み先はlocalhostになります。

サーバとの通信方法も検討する必要があるため、場合によっては本体のコードへ手を加える必要があります。

ログの出力が微妙

細かい部分ではありますが、TravisCIのWebコンソールとkarmaの相性が悪いようでExecute SUCCESSの表示が若干乱れます。
(テストが失敗した場合は正しく表示されるため現状気にしていません)


実際の設定方法に関しては基本的にはkarma、TravisCIのドキュメントに書かれていますが、一点詰まる部分があったためその解決方法に関して紹介したいと思います。

TravisCI上のChrome(Ubuntu Chronium)はバージョンが古い

現在提供されているTravisCIのChrome(Chronium)のバージョンはChromium 37.0.2062です。 また、上記Issueにも上げられていますが、標準だとFirefoxもバージョンが古いため注意が必要です。

これに関しては「sudo apt-getする」方法が紹介されていますが、sudo apt-getするためにはsudo: requiredも必要になります。

そのため、弊社では.travis.ymlに以下のような指定を行っています。

addons:
  firefox: "latest" # この指定で最新のFirefoxが使用できる
before_script:
  - export FIREFOX_BIN=`which firefox`
  - export JPM_FIREFOX_BINARY=`which firefox`
script:
  - xvfb-run karma start --single-run

この構成であればsudo: falseのまま実行できるため、あとは普通にkarmaからFirefoxへ接続する指定を行えば、TravisCI上で最新のFirefoxを使ったテストが実行できます。 (2016/7/26 コメントを頂き、xvfbの設定を削除しxvfb-runを使うように修正しました。ありがとうございました)