初めてDocker + RailsでE2EテストしようとしてWebdrivers::BrowserNotFound: Failed to find Chrome binary. エラーにはまった時の話


たくさん詰まったのでこんなことがあったよという備忘録として残しておきます。

まず最初に参考にした記事
https://qiita.com/at-946/items/e96eaf3f91a39d180eb3

上記の記事を参考に実装してみたが、ブラウザがないとエラーが出てこける。なぜ。。。

Failure/Error: driven_by :remote_chrome 
Webdrivers::BrowserNotFound: Failed to find Chrome binary. 

色々調べると通常のテストは通っているが、javascriptのテスト(js:true)をしようとすると上記のエラーでコケるっぽい。

  config.before(:each, type: :system, js: true) do
    driven_by :remote_chrome
    Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
    Capybara.server_port = 3000
    Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
  end

↑なので参考にした記事の、ここの部分がうまく動いていない...?

chromeのコンテナを確認してみる

http://localhost:4444/wd/hubにアクセスしてみる。

表示を見る感じちゃんと動いているっぽい。

webコンテナからchromeコンテナに通信が届いているか確認

webコンテナ上でシェルを起動

$ docker-compose run --rm web sh

通信が通っているか確認

$ ping chrome
64 bytes from ... 

と文字がずっと流れているのを確認。どうやらちゃんとwebコンテナとchromeコンテナはつながっている様子。
ますますわからない。。。

その他いろんな記事を参考に書き足したり消したりしても何しても

Failure/Error: driven_by :〇〇〇
Webdrivers::BrowserNotFound: Failed to find Chrome binary. 

のエラーに苦しみました。

ちなみにDockerfileはこんな感じ。

Dockerfile
FROM ruby:2.6.6-alpine3.11
RUN apk --no-cache add tzdata \
                       libxml2-dev \
                       curl-dev \
                       make \
                       gcc \
                       libc-dev \
                       g++ \
                       bash \
                       mariadb-dev \
                       mariadb-client \
                       yarn \
                       sqlite-dev

RUN gem install bundler -v "2.0.2"

RUN mkdir /myapp
WORKDIR /myapp

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install

COPY . /myapp

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

EXPOSE 3000
CMD ["bundle", "exec", "falcon", "--verbose", "serve", "-p", "3000", "-b", "http://0.0.0.0"]

いったん最初から考えていく

コピペでつまってどうにも行かなくなってしまったのでいったん振出しに戻る。

ブラウザ(E2E)テストをするときには何が必要?

  • Webブラウザ
    Chrome, Firefox, IE, Opera など

  • WebDriver
    ブラウザを操作するための API を公開するモジュール

  • Selenium
    WebDriver と通信しプログラムからブラウザを操作するライブラリ

(こちらから引用 https://qiita.com/Chanmoro/items/9a3c86bb465c1cce738a)

ブラウザのテストをする際にはこの3つが必要となる。
Dockerでの環境だと上記がそろっていないので全部用意する必要がある。

また、ブラウザの用意の仕方について、
- chromeをrails環境と一緒のイメージでbuildする
- chrome用コンテナをdocker-composeに追加する
- chrome用コンテナをdockerコマンドで立ち上げる
などいろいろなやり方がある。

①新しくrails newで作ったアプリで試してみる

最初に参考にした記事https://qiita.com/at-946/items/e96eaf3f91a39d180eb3ではやっぱり動かず。。。

②別の記事を参考にしてみる

https://qiita.com/ngron/items/f61b8635b4d67f666d75#comments
次はこちらの記事を参考にしてみる。するとrails newしたアプリでは動いた!少し前進!

けどもともとテストコードを実装したかったアプリではエラーが出ました。
その時のエラーがこちら。

/bin/sh: apt-get: not found

エラー文で調べると、こちらの記事がヒット。
https://qiita.com/HorikawaTokiya/items/a2a174680d7dd759ccae

Alpine Linux????Ubuntu???なんでOSの話...?

③既存アプリとrails newで作成したアプリの違いを考える

OS設定しているところなんかあったっけ...?と思いつつrails newしたアプリと既存のアプリで違う記述のところを探してみる。

Dockerfile
FROM ruby:2.6.6
Dockerfile(既存アプリのほう)
FROM ruby:2.6.6-alpine3.11

あ!Alpineって書いてる!でもどういうこと...???
docker imageについてコンテナを作るために必要なものくらいの認識でいたので、いきなりOSの話が出てきてしかもrubyイメージにOSの記述があるので??状態になりました。

以下エンジニアの方に教えていただいたこと(ありがたい。。。)

AlpineはパッケージマネージャにAPKを使ってて、DebianとかUbuntuはAPTを使ってる。
パッケージマネージャはiPhoneのApp StoreとかAndroidのPlayストアみたいにそのOSにインストールできるツールとかアプリを提供してる場所みたいなもの。
パッケージマネージャはOS(というか派閥みたいなもの)で分かれてて、それぞれインストールアプリが微妙に違います。
あと同じアプリ、例えばMySQLでもAPTだと mysql-server って名前だったり、APKだと mysql だったりでこれまた微妙に違います。

OSがなぜ違うのかはDockerの場合、使ってるイメージによって変わります。

例えばRubyのイメージ
https://hub.docker.com/_/ruby

2.5.8〜3.0.0まであるけど、それぞれその後ろに付いてるalpineとかslimってのがOS名(かOSのコードネーム)

APTとAPKはそれぞれがアプリケーションだと思ってくれたらよくて、APTとAPKは違うアプリケーションなので使い方も違う。

④rubyイメージをubuntuのものに変えてみる

特にalpineを使う理由がなかったため、既存のアプリのrubyもubuntuのものに書き換えました。
すると先ほどのこの記事https://qiita.com/ngron/items/f61b8635b4d67f666d75#commentsの通りに進めたら既存アプリでもjsのテストが通るように!長かった。。。

結論

結局最初に参考にした記事ではなぜうまくいかなかったのかがわかりませんでした。
ただうまくいかなかった記事は chrome用コンテナをdocker-composeに追加する方法で、うまくいった記事はchromeをrails環境と一緒のイメージでbuildする方法だったので前者はバージョンの違い等の何らかの理由でwebコンテナとchromeコンテナの連携ができてなかったのかな?(ping chromeは通ってたのが謎ですが...)

今回色々な記事を試してみてイメージにOSの違いとかあるのを知れて勉強になりました。