【IaCで作るselenium環境】01_selenoidを構築する

――――――――――――――――――――――――――――――――――
【2021-01-20 更新】
VideoRecorderはSelenoidが勝手に起動してセッション張るので、docker-composeに書かなくていいですよ、とご指摘を頂きました。
ありがとうございました。

それを踏まえて内容に1部修正を加えています。
――――――――――――――――――――――――――――――――――

こんにちは。SHIFTのスクラムマスター・テスト自動化エンジニアの石丸です。

今回から数回にわけて、テスト⾃動化で役⽴つ取り組みとどなたでも出来る実践⽅法をソースコードを交えてお伝えしようと思います。


今回は初回ということもあり、ちょっと前段の前置きが⻑いです。
構築だけ知りたいよ︕という⽅は、「Selenoidの準備」までお進みください。


■今回のテーマ

今回のテーマは「selenoid」です。

Selenoidとは︖
https://aerokube.com/selenoid/
DockerコンテナでSeleniumの実⾏とブラウザ環境を物凄く簡単に作成できるプロダクトです。

クライアントマシン環境をあっという間に準備しましょうー。

■前提

Dockerが必要になります。
Docker Desktopをインストールしておいてください。
https://www.docker.com/products/docker-desktop

また当エントリは、windows環境をベースに記載しています。
何卒ご了承ください。

■E2Eテストの課題とアプローチ⽅法

E2Eでテストを実⾏しようとした場合、恐らく皆さんは以下のような作業が必要になってくると思います。

自動化作業のキー要素

現代のE2Eテスト⾃動化では実⾏時間短縮とともに、上記の作成リードタイムをいかに短縮するかが⼤きなポイントになっています。
そして今回のテーマであるSelenoidの導⼊では、クライアントマシン準備を⾼速化します。

■クライアントマシンの準備って⼀般的にどうやるの︖

今回はSeleniumを前提として話を進めます。

ローカル環境であればSeleniumを使って⾃マシンにあるブラウザを媒介してテストを実⾏することになると思います。
その際に必要となるのはSelenium本体とブラウザを起動するwebdriverです。

通常の構成

Selenium本体とWebDriverは後からインストールします。
これにより、テストコードからWebDriverを経由してブラウザを起動する命令が実⾏され、実際にブラウザが勝⼿に動き出すわけです。

■Selenium 問題その1「常に付きまとうバージョン管理」

Seleniumを使⽤していると、必ず発⽣するのがバージョン管理問題です。
 ・Selenium本体のバージョン
 ・WebDriverのバージョン
 ・実際のブラウザのバージョン

このどれかひとつでも、それ以外と合わないと起動しません。
しかもどのプロダクトのどのバージョンがどれと相性が悪くて動かないのかにわかに判別できないのがツライ。。

たまにWebDriver⾃体のバグで突然動かなくなることもあって、こんなときは悲惨です。

WebDriverおかしい︖

WebDriverをダウングレードする

テスト動かない︕

どのバージョンが相性悪い︖(Seleniumと︖ブラウザと︖)

カオス︕

となったりします。

つまり、上記プロダクト別にバージョン管理をしなければならないのです。
ほかの誰でもない、あなたがです。

■Selenium 問題その2「ブラウザ環境がテスト分離できない」

良く起きるシチュエーションとしては、ブラウザがオートアップデートになっており、SeleniumおよびWebDriverのバージョンと整合が無くなるパターンです。
最新のWebDriverが提供されていない場合はブラウザのダウングレードをするしかありません。

ではブラウザのダウングレードを⾏えばいいかというと、そう簡単でもありません。

<各プロダクトのバージョンダウン⼿順>
chrome
https://support.google.com/chrome/a/answer/7125792?hl=ja
firefox
https://support.mozilla.org/ja/kb/install-older-version-of-firefox

こんな⼿間やリスクをかけてダウングレードしますか︖
テストの世界では常識ですが、テスト環境は通常環境とは切り離してテストをするものです。
が、Seleniumをそのまま使うと「いつも使ってるブラウザ」に相乗りするので、テストを分離しづらいという問題が発⽣します。

■Selenoidで環境を分離をしよう

前置きが⻑くなりましが、ここでSelenoidさんが登場します。

Selenium本体とブラウザ環境(正確にはWebDriverと対象ブラウザ)をコンテナという形で提供するプロダクトです。
なんとWebDriverとブラウザのバージョン整合はコンテナが担保してくれます。
さようなら︕バージョン調整作業。
ローカルPC(windows、macOS)にDocker Desktopさえ⼊っていれば動きます。

(余談)
zalenium等、同じようにコンテナで環境を整えるプロダクトがあったりしますが、selenoidは圧倒的にイメージが軽いです。
私は最初zaleniumで環境を整えていましたが、他ならぬzaleniumのissueでselenoidをめちゃくちゃ褒めている⽅がいて知りました。
https://github.com/zalando/zalenium/issues/116#issuecomment-305246957

■Selenoidの準備

準備に3つの手順があります。

⼿順1︓docker-compose.ymlの準備
以下ののdocker-compose.ymlファイルを準備しましょう。

例⽰のパス
c:\tmp\docker\selenoid
(任意の場所で構いません)

docker-compose.yml

version: "3.7"
services:
 selenoid:
   container_name: selenoid
   image: "aerokube/selenoid:1.10.0"
   network_mode: bridge
   restart: always
   ports:
     - "8083:4444"
   volumes:
     - "./config:/etc/selenoid"
     - "/var/run/docker.sock:/var/run/docker.sock"
     # - "./video/:/opt/selenoid/video/"
     - "/c/tmp/docker/selenoid/video/:/opt/selenoid/video/"
     - "./logs/:/opt/selenoid/logs/"
   environment:
     - OVERRIDE_VIDEO_OUTPUT_DIR=/c/tmp/docker/selenoid/video
   command: >
     -conf /etc/selenoid/browsers.json
     -video-output-dir /opt/selenoid/video
     -log-output-dir /opt/selenoid/logs
   healthcheck:
     test: ["CMD-SHELL", "stat /opt/selenoid/logs/ || exit 1"]
     interval: 10s
     timeout: 10s
     retries: 3
     start_period: 30s
 selenoid-ui:
   container_name: selenoid-ui
   image: "aerokube/selenoid-ui:latest-release"
   network_mode: bridge
   restart: always
   links:
     - selenoid
   ports:
     - "18080:8080"
   command: ["--selenoid-uri", "http://selenoid:4444"]

(2021-01-20修正)
volumesの指定をOVERRIDE_VIDEO_OUTPUT_DIRと合わせています。
こうすることにより、Selenoidが生成したVideoRecorderとVolumeを共有します。

なお以前は書いていた以下記述は不要です。

 videorecorder:
   container_name: video-recorder
   image: selenoid/video-recorder:6.2
   restart: always
   healthcheck:
     test: ["CMD-SHELL", "stat /var/ || exit 1"]
     interval: 10s
     timeout: 10s
     retries: 3
     start_period: 30s

Selenoidが起動した際、SelenoidのVideo起動設定がtrueになっていれば自動的に立ち上がり、テスト後自動的に落ちます。
併せて手順3にも変更が入りますのでご確認ください。


⼿順2︓browsers.jsonの準備
Selenoidのブラウザ環境設定ファイルを配置します。
以下のbrowsers.jsonを準備しましょう。

例⽰のパス
c:\tmp\docker\selenoid\config
(任意の場所で構いませんがdocker-composeのvolumes指定と合わせてください)

browsers.json

{
   "chrome": {
       "default": "84.0",
       "versions": {
           "84.0": {
               "image": "selenoid/vnc_chrome:84.0",
               "port": "4444",
               "tmpfs": {"/tmp": "size=512m", "/var": "size=128m"},
               "path": "/"
           },
           "83.0": {
               "image": "selenoid/vnc_chrome:83.0",
               "port": "4444",
               "tmpfs": {"/tmp": "size=512m", "/var": "size=128m"},
               "path": "/"
           }
       }
   },
   "firefox": {
       "default": "78.0",
       "versions": {
           "78.0": {
               "image": "selenoid/vnc_firefox:78.0",
               "port": "4444",
               "tmpfs": {"/tmp": "size=512m", "/var": "size=128m"},
               "path": "/wd/hub"
           },
           "77.0": {
               "image": "selenoid/vnc_firefox:77.0",
               "port": "4444",
               "tmpfs": {"/tmp": "size=512m", "/var": "size=128m"},
               "path": "/wd/hub"
           }
       }
   }
}

⼿順3︓ブラウザイメージのpull
browsers.jsonで指定したイメージを事前にローカルPC内に準備しておきます。
windowsの場合はPowerShellから、macの場合はterminalから以下のコマンドを叩きましょう。

> docker image pull selenoid/vnc_chrome:83.0

実⾏後は以下のように出⼒されます。

83.0: Pulling from selenoid/vnc_chrome
5bed26d33875: Pull complete
f11b29a9c730: Pull complete
930bda195c84: Pull complete
78bf9a5ad49e: Pull complete
612deb543673: Pull complete
ae1b52a38346: Pull complete
052dcddf9428: Pull complete
d47a27d2875e: Pull complete
749b63c21378: Pull complete
c5eb7e28fb18: Pull complete
bcdd8ae347ed: Pull complete
65a7ddec35b0: Pull complete
dac38889f7dc: Pull complete
81e6fcd41103: Pull complete
1f6983c4b41b: Pull complete
Digest: sha256:019cba6874388000b4d5fdd4873b7b78545091acddf2b9595462e49553aecdbc
Status: Downloaded newer image for selenoid/vnc_chrome:83.0
docker.io/selenoid/vnc_chrome:83.0

※以下も同様に実⾏します。

docker image pull selenoid/vnc_chrome:84.0
docker image pull selenoid/vnc_firefox:76.0
docker image pull selenoid/vnc_firefox:77.0

(2021-01-20修正)
さらにVideoRecorderのイメージをpullしておきます。

docker image pull selenoid/video-recorder:latest-release

――――――――――――――――――――――――――――――――――
【注意】
なおlatest-releaseとは別にlatestというイメージがありますが、2年以上前のイメージなので絶対に使ってはなりません。
――――――――――――――――――――――――――――――――――

以上で準備は完了です。早速実⾏してみましょう。

■Selenoidの起動

実⾏にはdocker-composeコマンドを使います。
docker-compose.ymlがあるパスまでcdしてコマンドを実⾏します。

> cd C:\tmp\docker\selenoid\
> C:\tmp\docker\selenoid> docker-compose up -d

実⾏後は以下のように出⼒されます。

Creating network "selenoid_default" with the default driver
Pulling selenoid (aerokube/selenoid:latest-release)...
latest-release: Pulling from aerokube/selenoid
Digest: sha256:ed5cd4ba7d8de40a514667684484dfac34e5ad7d38d875f86bde5bda51e675c8
Status: Downloaded newer image for aerokube/selenoid:latest-release
Pulling selenoid-ui (aerokube/selenoid-ui:latest-release)...
latest-release: Pulling from aerokube/selenoid-ui
Digest: sha256:e38808b6a0f9514a23fd5600b48dbcbdf5aaa400dece6fef192ac6454dd67d93
Status: Downloaded newer image for aerokube/selenoid-ui:latest-release
Pulling videorecorder (selenoid/video-recorder:latest-release)...
latest-release: Pulling from selenoid/video-recorder
Digest: sha256:7c8804c5567bb24e76e952bc752c911105a3cccc9003c85dceed1bc3cad99b34
Status: Downloaded newer image for selenoid/video-recorder:latest-release
Creating selenoid ... done
Creating video-recorder ... done
Creating selenoid-ui ... done

doneになってますね。
実⾏後にhealthcheckをしています。

> docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------
selenoid /usr/bin/selenoid -listen ... Up (healthy) 0.0.0.0:8083->4444/tcp
selenoid-ui /selenoid-ui --selenoid-ur ... Up (healthy) 0.0.0.0:

全てhealthyになってますね。
この時点でノーマルなSeleniumから、以下のような構成に変わりました。

Selenoidの構成

■実⾏状況を確認するプロダクト「Selenoid-UI」

ここまでで、ひとつ説明をしていないプロダクトがあります。それがSelenoid-UIです。
https://aerokube.com/selenoid-ui/latest/

今回ローカル環境のブラウザを使わない代わりにコンテナ上にブラウザを⽴てています。
ですがコンテナ内に表⽰されているブラウザは通常の⽅法では閲覧できません。
この時に使⽤するお便利ツールとして、Selenoid-UIが準備されています。
既にお気づきかもしれませんが、docker-composeでup済みです。

ブラウザのURLから以下にアクセスしてみてください。
http://localhost:18080/#/

以下のような画⾯が出てくればSelenoidがブラウザコンテナの起動をListenしています。

画像4

■Selenoidのデメリット

ここまで読まれていて「あれ、最初あったEdgeが途中から無くなってるなぁ」と思ったあなたは鋭い。Selenoidを使う場合は、IE、Edge、Safariは使⽤除外となります。
(SelenoidはDockerで起動している=Linuxカーネル上で動く)

※Linuxブラウザで8割をカバーしているから問題ない、というのが作者の主張
https://www.slideshare.net/IvanKroutov/selenoid-browsers-in-containers

■まとめ

実際の構築⼿順

1. 指定のdocker-compose.ymlを準備する
2. 指定のbrowsers.jsonを準備する
3. 実⾏したいブラウザのイメージを事前にpullしておく
4. Selenoidコンテナを起動する

というわけで、今回はSelenoidの準備までご説明しました。

ブラウザ環境を整えたら、次はやっぱりテストを実⾏したいですよね。
次回は⽐較的簡単に準備するテスト実⾏環境というテーマでお話しします。
ではでは。

――――――――――――――――――――――――――――――――――

執筆者プロフィール:石丸圭
スクラムを中心にテストのアジリティーを高めるべく
日々仕事のリードタイム・プロセスタイムの圧縮に奮闘中。
6歳4歳0歳児のパパ。
MUPうさぎクラス。

個人的なご相談はインスタDMにてどうぞー。
Instagram:@theboyalex

【ご案内】
テスト自動化のご相談は以下までお気軽にご連絡ください。
https://forms.office.com/Pages/ResponsePage.aspx?id=IkyjGtUOzUeqMMEbzjGdlSf__O4V1URMn-5BpGP8xd9UNE9ESkRPUEs1Wk9FM0REU1BXODFBSkI0MC4u

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/