Docker で Selenium Grid の環境構築をもっと楽に!

こんにちは、kintone チームの宮田です!

今回は、Selenium/Appium Advent Calendar 2014 15日目の記事として、Docker を使った Selenium Grid の環境構築方法について説明します。

背景

kintone チームでは、Selenium Grid を使用して Selenium テストを並列化しています。これまでは、VM で環境構築していたのですが、VM 数が増えてくるにつれてメンテナンスコストが上がってきたので、Docker による楽な環境構築方法をチームで探求していました。そこにいいタイミングで本家の Docker イメージのリポジトリが作成されていたので、使ってみることにしました。

Docker のインストール

OS は、Ubuntu 14.04 を使用します。

公式HPでは、docker.io パッケージのインストールと lxc-docker パッケージのインストールが紹介されていますが、Docker のバージョンが古いと Selenium の イメージが一部動作しない部分があるので、よりバージョンが新しい lxc-docker パッケージでインストールします。

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
$ sudo sh -c "echo deb https://get.docker.com/ubuntu docker main\
> /etc/apt/sources.list.d/docker.list"
$ sudo apt-get update
$ sudo apt-get install lxc-docker
$ docker --version
Docker version 1.3.2, build 39fa2fa

Selenium の Docker イメージの種類

Selenium 本家の Docker イメージは以下のものがあります。

イメージ名 説明
selenium/hub Selenium Grid の Hub を起動するイメージ
selenium/node-chrome Chrome が使用可能な状態で Selenium Grid の Node を起動して Hub に接続するイメージ
selenium/node-firefox Firefox が使用可能な状態で Selenium Grid の Node を起動して Hub に接続するイメージ
selenium/node-chrome-debug selenium/node-chrome に VNC サーバーがインストールされたもの
selenium/node-firefox-debug selenium/node-firefox に VNC サーバーがインストールされたもの

VNC サーバーが入っていると、Selenium テストが流れている様子を確認するのに便利なので、今回は debug 版のイメージを使用します。

Grid 構築

$ docker run -d -p 4444:4444 --name selenium-hub selenium/hub:2.44.0
$ docker run -d -v /dev/urandom:/dev/random -P --link selenium-hub:hub selenium/node-chrome-debug:2.44.0

これだけで Hub と Node が起動されます。初回はダウンロードなどで時間がかかりますが、2回目移行は一瞬で立ち上がります。"-v"オプションでvolumesの設定をしないと、ノードの登録にとても時間がかかる問題が発生するのでご注意ください。

動作確認

まずは、http://localhost:4444/grid/console にアクセスしてみましょう。以下のようなGridのコンソール画面が表示されれば成功です。

console

次に、せっかくなので VNC で接続してみます。まずは VNC のポートを取得する必要があります。

$ docker ps
CONTAINER ID        IMAGE                               COMMAND                CREATED             STATUS              PORTS                     NAMES
325f7dbb18a9        selenium/node-chrome-debug:2.44.0   "/opt/bin/entry_poin   3 seconds ago       Up 2 seconds        0.0.0.0:49154->5900/tcp   jolly_shockley      
b67bff888d17        selenium/hub:2.44.0                 "java -jar /opt/sele   15 minutes ago      Up 15 minutes       0.0.0.0:4444->4444/tcp    selenium-hub
$ docker port 325f7dbb18a9 5900
0.0.0.0:49154

これでローカルの取得できたポートに VNC で接続(上の例の場合 127.0.0.1:49154 に接続)します。デフォルトのパスワードは「secret」です。接続に成功すると以下のような画面が表示されます。

vnc

では、いよいよ Selenium を使ってブラウザを起動してみましょう。python でサクッと動かしてみます。

$ sudo apt-get install python-pip
$ sudo pip install selenium
$ python
> from selenium import webdriver
> from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
> driver = webdriver.Remote(
    command_executor='http://127.0.0.1:4444/wd/hub',
    desired_capabilities=DesiredCapabilities.CHROME)
> driver.get("https://kintone.cybozu.com")

下の画像のように kintone のホームページが開きます!技術記事に見せかけた宣伝成功です!

kintone

設定を変える

実際に運用するにあたって、Selenium Grid の設定を変えたい場合があります。

例えば、自分が実験した感じだとたまにブラウザがハングしてテストがずっと止まったままになってしまうことがあったので、Hub にタイムアウトの設定を追加したくなりました。なので、差し替えるための config.json を用意します。newSessionWaitTimeout と browserTimeout の値を元の設定ファイルから書き換えています。

{
  "host": null,
  "port": 4444,
  "newSessionWaitTimeout": 600000,
  "servlets" : [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 5000,
  "cleanUpCycle": 5000,
  "timeout": 30000,
  "browserTimeout": 60000,
  "maxSession": 5,
  "jettyMaxThreads":-1
}

次に、Dockerfile を用意します。本家のイメージをベースに config.json だけ置き換えます。

FROM selenium/hub:2.44.0

#=======================
# Overwrite config.json
#=======================
COPY config.json /opt/selenium/config.json

これらのファイルは、こちらのリポジトリで公開しています。

そして、Dockerfile がある HubOverwriteConfig ディレクトリを指定してビルド、起動します。事前に先ほど起動したコンテナを停止するのを忘れないようにしてください。

$ docker build -t cybozu/selenium-hub HubOverwriteConfig
$ docker run -d -p 4444:4444 --name selenium-hub cybozu/selenium-hub

コンソール画面を開いて設定を確認すると、下の画像のようにタイムアウトが設定されているのが分かると思います。やったー!

overwrite_config

figの導入

ノード数を増やしたくなった場合、docker run コマンドを毎回叩いてもいいですけど、ノード数が多くなってくるとさすがに面倒です。なので、figという複数の Docker コンテナを一度に操作するためのツールを導入します。

$ sudo sh -c "curl -L https://github.com/docker/fig/releases/download/1.0.1/fig-`uname -s`-`uname -m` > /usr/local/bin/fig; chmod +x /usr/local/bin/fig"

fig は、YAML 形式で定義します。

hub:
  build: ./HubOverwriteConfig
  ports:
    - 4444:4444

node:
  image: selenium/node-chrome-debug:2.44.0
  links:
    - hub
  ports:
    - 5900
  environment:
    SCREEN_WIDTH: 1280
    SCREEN_HEIGHT: 800
  volumes:
    - /dev/urandom:/dev/random

では、起動してノード数を一気に増やしてみます。

$ fig up -d
$ fig scale node=8

コンソールで確認してみると、これだけでノード数が8つに増えました!これで大規模な Grid を組むのも楽ちんですね!

scale

まとめ

ということで、Docker のおかげで Selenium Grid 環境の構築が楽にできるようになりました。実はこれ、メンテナンス面でもかなり楽になります。例えば、WebDriver のバージョンアップがあっても、新しいイメージを用意してコンテナを作りなおすだけです。

また、手元で軽く Selenium テストを流すときにも Docker の独立した環境は役に立ちます。普通に Selenium テストを流すとブラウザに邪魔されて他の作業ができなくなりますが、Docker を使えばローカル環境でテスト実行と別の作業を並行して行うことができるようになります。

デメリットとしては、Linux 以外の OS でテストができないことでしょうか。例えば、IE でテストするための環境構築には、この方法は使えません。Windows の Docker 対応が望まれますね。

Docker はまだまだ枯れていない技術なので、プロダクトで使うには勇気がいりますが、今回のテスト環境構築のように開発ツールとしてならとても便利に活用できます。

皆さまもぜひ楽しい Selenium ライフを!

Advenn Calendar の明日の記事は、・・・あれ?まだ誰が書くか登録されてない?実は昨日・一昨日も書く人がいなかったみたいなので、どなたか是非ともよろしくお願いします!