文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

DockerとSeleniumGridとNightwatchでE2Eテストを始めよう

Dockerで簡単に始められますよ〜 Nightwatchならライトにサクッと書けますよ〜
f:id:treeapps:20161124012643p:plain

皆さんはE2E(end to end)テスト、してますか?

今回はDocker、Selenium grid、Nightwatchを使ったE2Eテスト(ブラウザテスト)の環境構築からテスト実行、VNCでテスト実行の様子を確認するところまでやってみようと思います。

技術要素

  • Selenium Grid v3.0.1
  • Nightwatch v0.9.9
  • docker v1.12.1
  • node.js v7.2.0

なぜNightwatchなのか

沢山あるE2Eテストフレームワークの中で今回Nightwatchを選択したのですが、理由は以下の通りです。

  • javascriptでテストを記述できること。
  • 使い方が簡単であること。
  • 環境構築が楽であること。
  • 単独で動くこと。
  • assertの仕組みが内蔵されていること。
  • 高機能でなくていいので、コード記述量が少なく済むこと。

ざっくり言うと、「簡単に環境構築できて、簡単に動作すること」です。

まず、記述言語はjavascriptに限定しました。以前業務でjava + selenium webdriverでゴリゴリしていましたが、辛いです。あれは辛いです。いちいちコンパイルが必要だったり、環境面も優しくありませんでした。もっとカジュアルに記述できて、コンパイル無しで動くものにしました。

Protractorもいい感じに見えたのですが、Angular.jsのために作られたものだそうで、個人的には特定のFWに依存していたりする事が嫌だったのと、nightwatchと比較するとコード記述料が多いため、見送りました。

nightwatchであれば、nightwatch本体もchromeドライバーもfirefoxドライバーもselenium-standaloneも、全て「npm install」一発で環境を用意する事ができます。テストもjsでさっくり記述でき、コンパイル無しで即実行可能なので、相当楽に動かす事ができます。

環境構築

Dockerが無い時代はSelenium Gridの環境構築は非常に難しく、メンテナンスコストも高いものでした。

しかしDocker時代となった今、大変簡単に環境構築ができてしまいます。

dockerとnode.jsさえあればすぐテスト実行できちゃいます。

docker

docker for mac か docker for windowsをインストールして下さい。

[mac] https://docs.docker.com/docker-for-mac/

[windows] https://docs.docker.com/docker-for-windows/

node.js

macならnodebrew、windowsならnodist等を使い、node.jsをインストールして下さい。

for mac
nodebrew install-binary v7.2.0
nodebrew use v7.2.0
nodebrew alias default v7.2.0
for windows
nodeist stable v7.2.0
nodeist use v7.2.0
nodeist alias default v7.2.0

テストの準備

nightwatchを実行するための準備をします。

dockerコンテナ

最初はmac上でdocker-machineを使わずにdocker-compose upしてみたのですが、以下のように127エラーが起きてしまいました。linux(Amazon linux)上ではdocker-machine無しで上手くいきました。

tree:test tree$ docker-compose ps
                 Name                             Command             State          Ports
------------------------------------------------------------------------------------------------------
seleniumgridnightwatchexample_chrome_1    /opt/bin/entry_point.sh   Exit 127
seleniumgridnightwatchexample_firefox_1   /opt/bin/entry_point.sh   Exit 127
seleniumgridnightwatchexample_hub_1       /opt/bin/entry_point.sh   Up         0.0.0.0:4444->4444/tcp

エラーが出てしまうので、ちょっと嫌ですがdocker-machineで専用ホストを作成します。

$ docker-machine create -d virtualbox selenium
$ eval $(docker-machine env selenium)

vmwarefusionを持っている場合、-dの引数を「vmwarefusion」に変えて下さい。vmwarefusionの方が1.5倍程高速です。

git clone

例によって既にすぐテストできるプロジェクト一式をgithubにアップしています。

git clone https://github.com/treetips/selenium-grid-nightwatch-example.git

github.com

node_moduleの依存

package.jsonを用意してあるので、以下のコマンド一発で依存モジュール類が揃います。今回はnightwatchはglobalにインストールせず、ローカルにインストールする形にしました。

$ npm install

nightwatchの設定

nightwatch.conf.jsを開き、「selenium_host」にdockerのホストを設定して下さい。ホストは以下のコマンド確認することができます。

tree:selenium-grid-nightwatch-example tree$ docker-machine ip selenium
172.16.53.136

docker-hub

docker-hubのイメージを使用するので、アカウントが無い方はアカウントを作成して下さい。
https://hub.docker.com/

続いて、初回docker pull実行時はログインを求められるので、先に以下のようにdocker loginでログインしておきます。

tree:test tree$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username (treetips): treetips
Password:
Login Succeeded

ログインが成功すると、認証情報が以下の場所に保存され、以降はdocker loginは不要になります。

tree:test tree$ ll ~/.docker/config.json
-rw-------  1 tree  staff   188B 11 23 19:48 /Users/tree/.docker/config.json

Nightwatchでテストを実行する

ローカルでテストする場合

ローカルの場合はいちいちVNC経由で動作を確認したくないので、selenium-standaloneを使ってローカルにインストールされたchrome,firefoxを直接実行したいですね。

そういう場合は以下のように実行して下さい。

$ npm run local

もしchrome、firefoxを単独で実行したい場合は以下のようにして下さい。

# test for chrome
$ npm run local-chrome

# test for firefox
$ npm run local-firefox

Selenium Gridで並列テストする場合

Selenium Gridを使って並列で一気にテストする場合は以下のようにして下さい。

dockerコンテナの起動

まず、Selenium Gridのdockerコンテナを起動します。

$ docker-compose up -d
Selenium Gridの動作確認

ブラウザから起動を確認します。
http://${dockerホスト}:4444/grid/console

以下ように起動しているノードが全て表示されます。
f:id:treeapps:20161124001158p:plain

Nighwatchを実行する

$ npm run grid

これで、Docker上のSelenium Gridに対して、chromeとfirefoxのブラウザテストを並列実行する事ができます。

Seleniumの実行状況をVNCで確認する

ローカルの場合はローカルにインストールされたchromeとfirefoxが起動するので、実行している様子を確認する事ができました。しかしSelenium Gridの場合は、linux等のサーバ上のchrome・firefoxが起動されます。サーバ側で実行されているchromeとfirefoxを閲覧するため、VNCを利用します。

幸い今回使用するchromeとfirefoxのdockerイメージは、最初からVNCサーバがインストールされているものを使っているので、VNCクライアントさえあればすぐ確認できます。

macの場合は、Finder -> メニューバーの「移動」 -> 「サーバに接続」をクリックすると、以下のように表示されます。
f:id:treeapps:20161124002454p:plain

テキストボックスに以下の2つをそれぞれ入力し、接続先を追加します。
vnc://${dockerホスト}:4501 (firefox用)
vnc://${dockerホスト}:4502 (chrome用)
(4501, 4502は、docker-compose.ymlのports要素で指定しています)

接続ボタンをクリックするとパスワードが聞かれます。パスワードは「secret」です。
f:id:treeapps:20161124003317p:plain

起動すると、以下のように表示されます。この状態でnightwatchでテストを実行すると、ここにブラウザが表示され、画面遷移する様子が視覚的に確認できます。
f:id:treeapps:20161124002950p:plain

実際にnightwatchを実行し、VNCでそれを確認した様子は↓こんな感じです。
f:id:treeapps:20161124004154g:plain

コンソールには、以下のようにカラフルに結果が表示されます。
f:id:treeapps:20161124005647p:plain

VNCクライアントを2つ(firefox用とchrome用)起動しておけば、両方同時に確認する事ができます。

もしnightwatchの実行時にエラーが発生した場合は、「selenium-grid-nightwatch-example/screenshots/test/Display-yahoo-->-search-->-assert_FAILED_Nov-24-2016-004001-GMT+0900.png」のようにスクリーンショットが保存されます。

雑感

Selenium Gridを初めて使ってみたわけですが、以外な程あっさり環境構築できました。Nightwatchについても環境構築は簡単でした。

しかしSeleniumでブラウザを操ると、ローカルでは問題無いのに、Gridの場合だけ特定ブラウザだけクラッシュしたりする事があったりしました。もしかしたらlinux版のfirefox・chromeの問題なのかもしれませんが、定かではありません。正直seleniumは扱いが難しく職人芸的な面もあるので、あまりやりすぎるとメンテできなくなって使われなくなる(実体験)ので、程々にするとよいです。

ちなみに私の場合は正直ほとんどメンテしたくないと考えているので、とりあえずTOPから目的の画面までの画面遷移のみしかテストしていません。

こういうテストってカジュアルさが重要なので、java + WebDriverでゴリゴリするのに抵抗がある方は、まずはDocker on Selenium Grid + NightwatchでライトにE2Eテストしてみると、どれくらいメンテが簡単・大変なのかの感覚が掴めるので、是非試して見る事をおすすめします!