New-Village

月間ブログ。だいたい1カ月に1回は更新しているようです。

NitrousでSelenium WebDriverを使う

前回記事でNitrousを使ってPython開発環境を作成しました。

その後、ダラダラとPythonチュートリアルをやっていたのですが、チュートリアルで使われているテストツールSeleniumが期待通りに動かず、対応にかなりの時間がかかりました(チュートリアルは別の記事で紹介します)。

f:id:New-Village:20151108125753p:plain

本当はチュートリアルの第一章を記事にしたかったのですが、テストツールがうまく動かなかったこともあって、今回は、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というアプリが存在している状態になっています。

f:id:New-Village:20151108114004p:plain

それでは、表題の件で直面したエラー内容と解消方法について書いていきたいと思います。

 

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 Found

E: 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