Hello Selenium!
Hello Selenium!
この記事について
Web ブラウザを操作するテスト自動化ツールである Selenium を,初めて触ってみて試した内容を紹介します.
最終的に下の gif アニメのように「検索エンジンに特定をキーワードを与えてやると,期待したサイトがトップヒットする」といった簡単なテスト (?) が実行できるようになりました.
今回行った実装は GitHub のリポジトリにも置いてあります.
Selenium とは
Selenium とは……
Selenium automates browsers. That's it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) be automated as well.
(https://www.seleniumhq.org より)
Selenium とはブラウザを自動化するもので,Web アプリのテスト自動化に使えるし,それだけでなくブラウザを使った単純作業の自動化もできる,といったところでしょうか.
Ruby で Selenium を動かす
セットアップ
Ruby で Selenium を動かすには,selenium-webdriver
という gem を使用します.
gem install selenium-webdriver
動かす Web ブラウザは,事前にインストールされている必要があります.今回は Firefox で試しました.
また,動かすブラウザを操作するための Selenium のドライバをインストールし,パスを通しておく必要があります.
Firefox を動かすには geckodriver
というライブラリが必要なので,https://github.com/mozilla/geckodriver/releases からダウンロードし,パスが通ったところに配置します.
macOS を使っているならば,homebrew でインストールできます.
brew install geckodriver
実際に動かす
Ruby のコードから Selenium の driver オブジェクトを取得します.
requrie 'selenium-webdriver' driver = Selenium::WebDriver.for(:firefox) driver.manage.timeouts.implicit_wait = 5
ここでは,Web ページの応答のタイムアウトを 5 秒に設定しています.
implicit_wait
を設定しておくと,プログラムを書く側で明示的に待ちを実装しなくても,ライブラリが勝手に 5 秒まで待ってくれるようになります.
driver を作成できたので,ブラウザを操作してみます. Selenium でブラウザを操作するには,要素の ID や XPath で対象を選択し, それに対して入力やクリックのメソッドを呼び出す形になります.
次のコードでは,
- 検索エンジンの DuckDuckGo を開く
- 検索ワードに "Ruby" と入力する
- 検索実行ボタンをクリックする
- 検索結果一覧から,トップヒットしているものをクリックする
という操作を行っています.
driver.get('https://duckduckgo.com') driver.find_element(:id => 'search_form_input_homepage').send_keys('Ruby') driver.find_element(:id => 'search_button_homepage').click() driver.find_element(:id => 'r1-0').click()
ついでに開いている画面のスクリーンショットを撮ることもできます. テストのエビデンスが求められるシチュエーションで活躍しそうですね!
せっかくなのでエビデンスとしてスクショを撮って,driver を quit して終わらせましょう.
driver.save_screenshot('./duckduckgo-ruby.png') driver.quit()
エビデンスを見ると,プログラミング言語 Ruby のサイトが最後に表示されていたことが確認できますね.
そういえば今回は,検索ワードに対して期待した結果がトップヒットするという「テスト」を書こうとしていたのでした. driver から現在のページの URL を取得すれば,検証が行えます.
assert_equal('www.ruby-lang.org', URI.parse(@driver.current_url).host)
ここまでの内容をまとめると,次のようなテストクラスにできます.
require 'selenium-webdriver' require 'test/unit' require 'uri' class SeleniumFirefoxTest < Test::Unit::TestCase def setup() @driver = Selenium::WebDriver.for(:firefox) @driver.manage.timeouts.implicit_wait = 5 # seconds end def teardown() @driver.quit() end def test_duckduckgo() @driver.get('https://duckduckgo.com') @driver.find_element(:id => 'search_form_input_homepage').send_keys('Ruby') @driver.find_element(:id => 'search_button_homepage').click() @driver.find_element(:id => 'r1-0').click() @driver.save_screenshot('./duckduckgo-ruby.png') assert_equal('www.ruby-lang.org', URI.parse(@driver.current_url).host) end end
GitHub のコード
ここまでの内容をもう少し拡張したものを GitHub のリポジトリ に置いてあります. リポジトリの中では,今回使用した DuckDuckGo 以外に
といったサイトでも検索を行うテストメソッドを用意しています.
ブラウザについては,今回の Firefox 以外に
- Firefox (Headless モード)
- Google Chrome
- Google Chrome (Headless モード)
で動かすテストクラスがあります. GUI がない環境でテストを実行する場合は,Headless モードで動かすことになります.
実行環境
上述のリポジトリにはテストコード以外に,Docker と Vagrant による実行環境がそれぞれ用意してあります. いずれの環境も Firefox が使えるようにしてあります.
画面にブラウザを表示して動く様子が見たい場合は Vagrant の仮想マシン,Headless モードを動かして見たい場合は Docker イメージが使えます.
Docker イメージは Docker Hub にも公開してあります: snobutaka/hello-selenium
おわり
今回は初めての Selenium ということで非常に簡単なテストを書いてみました.
仕事で使ってみたり,ブラウザ作業自動化ライフハックに使ったりしてみたいものです.