NitrousでSelenium WebDriverを使う
前回記事でNitrousを使ってPython開発環境を作成しました。
その後、ダラダラとPythonチュートリアルをやっていたのですが、チュートリアルで使われているテストツールのSeleniumが期待通りに動かず、対応にかなりの時間がかかりました(チュートリアルは別の記事で紹介します)。
本当はチュートリアルの第一章を記事にしたかったのですが、テストツールがうまく動かなかったこともあって、今回は、Nitrous環境上でSeleniumを動かす際のエラー解消手順を記述しておきます。
なお、本記事は主にエラー解消手順について記述しています。ベストプラクティスを知りたい方は、本記事の「最後に:PhantomJSを使う」を参照してください。
環境情報
実施した環境は以下のとおりの環境です。NitrousのContainerは初期状態のままです。Python Packageは、Django, selenium, mockとそれらが依存するパッケージがインストールされています。
(tutorial-env)→ ~ python -V
Python 3.4.0
(tutorial-env)→ ~ pip list
Django (1.8.6)
mock (1.3.0)
pbr (1.8.1)
pip (7.1.2)
selenium (2.48.0)
setuptools (18.5)
six (1.10.0)
ディレクトリ構成は、mysiteというプロジェクトの中に、mysiteとftsというアプリが存在している状態になっています。
それでは、表題の件で直面したエラー内容と解消方法について書いていきたいと思います。
Firefoxがない場合のエラー
右も左も分からない状態で、とりあえず、実施していたチュートリアル通りにSeleniumを実行したところ、以下のエラーに直面しました。実行したテストはSelenium with Pythonのサンプルコードをfts/test.pyに記述したものです。
(tutorial-env)→ mysite python manage.py test fts
Creating test database for alias 'default'...
E
============================================================
ERROR: fts.tests (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
Traceback (most recent call last):
(中略)
File "/home/nitrous/tutorial-env/lib/python3.4/site-packages/selenium/webdriver/firefox/firefox_binary.py", line 159, in _get_firefox_start_cmd
" Please specify the firefox binary location or install firefox")
RuntimeError: Could not find firefox in your system PATH. Please specify the firefox binary location or install firefox
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
原因と解決方法
Firefoxがインストールされていないと、上記のエラーが発生します。Firefoxをインストールすることで解消されます。
なお、Nitrous上でFirefoxを使ったSeleniumの実行を行う場合は、Xvfdのインストールも必要になります。
apt-get時のエラー
初期状態のNitrousのContainerでFirefoxをインストールしようとした場合、以下のエラーが出ます。
(tutorial-env)→ mysite sudo apt-get install firefox
(中略)
Fetched 5,709 kB in 26s (212 kB/s)
E: Failed to fetch http://mirror.nitrous.io/ubuntu/pool/main/s/systemd/libsystemd-daemon0_204-5ubuntu20.12_amd64.deb 404 Not FoundE: Failed to fetch http://mirror.nitrous.io/ubuntu/pool/main/a/apparmor/libapparmor1_2.8.95~2430-0ubuntu5.2_amd64.deb 404 Not Found
E: Failed to fetch http://mirror.nitrous.io/ubuntu/pool/main/s/systemd/libsystemd-login0_204-5ubuntu20.12_amd64.deb 404 Not Found
E: Failed to fetch http://mirror.nitrous.io/ubuntu/pool/main/s/systemd/systemd-services_204-5ubuntu20.12_amd64.deb 404 Not Found
E: Failed to fetch http://mirror.nitrous.io/ubuntu/pool/main/s/systemd/libpam-systemd_204-5ubuntu20.12_amd64.deb 404 Not Found
E: Failed to fetch http://mirror.nitrous.io/ubuntu/pool/main/g/gtk+2.0/libgtk2.0-common_2.24.23-0ubuntu1.2_all.deb 404 Not Found
E: Failed to fetch http://mirror.nitrous.io/ubuntu/pool/main/g/gtk+2.0/libgtk2.0-0_2.24.23-0ubuntu1.2_amd64.deb 404 Not Found
E: Failed to fetch http://mirror.nitrous.io/ubuntu/pool/main/f/firefox/firefox_39.0+build5-0ubuntu0.14.04.1_amd64.deb 404 Not Found
E: Failed to fetch http://mirror.nitrous.io/ubuntu/pool/main/g/gtk+2.0/libgtk2.0-bin_2.24.23-0ubuntu1.2_amd64.deb 404 Not Found
E: Failed to fetch http://mirror.nitrous.io/ubuntu/pool/main/u/ubufox/xul-ext-ubufox_3.0-0ubuntu0.14.04.1_all.deb 404 Not Found
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
(tutorial-env)➜ mysite which firefox
firefox not found
原因と解決方法
レポジトリ情報が古いことが原因のようです。レポジトリの更新を行うとエラーは解消されます。
(tutorial-env)→ mysite sudo apt-get update
(tutorial-env)→ mysite sudo apt-get install firefox
(中略)
(tutorial-env)→ mysite which firefox
/usr/bin/firefox
(tutorial-env)→ mysite firefox -v
Mozilla Firefox 42.0
XWindowが無い場合のエラー
Firefoxをインストールして、テストコードを実行させると以下のエラーに直面しました。実行したテストはSelenium with Pythonのサンプルコードをfts/test.pyに記述したものです。
(tutorial-env)→ mysite python manage.py test fts
Creating test database for alias 'default'...
E
============================================================
ERROR: fts.tests (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
Traceback (most recent call last):
(中略)
File "/home/nitrous/tutorial-env/lib/python3.4/site-packages/selenium/webdriver/firefox/firefox_binary.py", line 98, in _wait_until_connectable
raise WebDriverException("The browser appears to have exited "
selenium.common.exceptions.WebDriverException: Message: The browser appears to have exited before we could connect. If you specified a log_file in the FirefoxBinar
y constructor, check it for details.
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
原因と解決方法
XWindowがインストールされていない環境で、Webdriverをインスタンス化させようとするとエラーが発生します。
driver = webdriver.Firefox()
一般的に、XWindowをミュレートするXvfbというパッケージをインストールすることで回避するようです。
(tutorial-env)→ mysite sudo apt-get install xvfb
インストールが完了したらXvfbを起動します。
(tutorial-env)→ mysite export DISPLAY=:1
(tutorial-env)→ mysite Xvfb :1 -screen 0 1280x1280x24 >/dev/null 2>&1 &
(tutorial-env)→ mysite python manage.py test fts
Creating test database for alias 'default'...
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
参考サイト: Thanks! TISさん。
最後に:PhantomJSを使う
Firefoxを使ったSeleniumの実行方法について書いてきましたが、PhantomJSを使う方法もあります。PhantomJSは画面を持たない(Headless)Webkitベースのブラウザです。Xvfbを使い方法と異なり、毎回Xvfbを起動しなくて済むので、こちらの方が楽かもしれません。
PhantomJSをインストールします。Firefoxのインストールとは異なり、"apt-get update"しなくてもインストールできます。
(tutorial-env)➜ mysite sudo apt-get install phantomjs
Selenium with Pythonのサンプルコードの4行目
driver = webdriver.Firefox()
を以下のとおりに書き換えます。
driver = webdriver.PhantomJS()
この状態でテストを実行すると、FirefoxやXvfbを用意しなくてもテストが実行できます。
(tutorial-env)→ mysite python manage.py test fts
Creating test database for alias 'default'...
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK