プログラマでありたい

おっさんになっても、プログラマでありつづけたい

Selenium2.0 WebDriverで複数ブラウザのUIテスト もう一度、Selenium再入門


 ブラウザを使った自動テストツールの代表格であるSelenium。Firefoxのプラグインというイメージが強かったのですが、今では複数のブラウザを動かせるようになっています。更にサーバサイドからの起動も出来るので、ユニットテストの一部として組み込むことが出来ます。またSelenium 2.0系が出て、WebDriverというモノも出てきました。複数のプロジェクトがあって新旧の情報が入り交じっていますので、一度整理した上で使い方を学ぼうと思います。

Seleniumのプロジェクト


 恐らく多くの人がSeleniumと聞いて思い浮かべるのがSelenium IDEだと思います。Firefoxのプラグインとして、テストケースの開発を行う為のツールです。画面の操作を記録したり、それをテストケースという形で保存したりする機能を持っています。また、テストの再現も行います。

 別名Selenium RC。名前の通りSeleniumをリモート操作する為の機能です。サーバ側とクライアント側の2つから構成されています。サーバ側で指令をだして、クライアント側のブラウザで実行するという形式をとります。Javaを始めRuby,Python,perl,.Netと各種の言語に対応していて、ユニットテストに組み込むことも可能です。

  • Selenium Grid

 Selenium Remoteから派生して、複数のサーバで分散実行しようというプロジェクトです。Selenium 2.0からデフォルトの機能に統合されました。

  • Selenium WebDriver

 位置づけがややこしいのですが、Selenium 2.0というのが実はSelenium Webdriverです。Selenium RC (1.0)と全く別製品であったWebDriverを統合させたのがSelenium WebDriver(Selenium 2.0)です。後方互換もありますので、これから始める人は、Selenium Webdriverを使うのが良いでしょう。Firefoxだけでなく、IEやChrome,Opera。果てはiOSやAndroidのテストとかも出来るようです。

使い方 〜How to use


ダウンロード

ダウンロード対象のモジュールは3つあります。いずれもダウンロードページから入手できます。

  • Selenium IDE

 Firefoxのプラグインです。一番最初のテストケースを作る時に重宝します。

  • Selenium Server (formerly the Selenium RC Server)

 メインとなるモジュールです。Javaのjarで、サーバ側とクライアント側の両方に配置することになります。

  • Selenium Client Drivers

 名前が何だかなぁという感じですが、プログラムから利用する為のモジュールです。Java,C#,Ruby,Pythonが用意されています。

サーバ側の起動(IPを192.168.0.1とします。)

サーバ機とクライアント機は同じでも問題ありません。またプログラムを実行するサーバと同一でも大丈夫です。

java -jar selenium-server-standalone-2.15.0.jar -role hub
クライアント側の起動

当然ながら、クライアント側はGUIが必要になります。またテストするブラウザも必要になります。IEのテストするなら、IEがインストールされている必要があります。

java -jar selenium-server-standalone-2.15.0.jar -role webdriver -hub http://192.168.0.1:4444/grid/register


Rubyのサンプルプログラム(IEが立ち上がります)

require 'rubygems'
require 'selenium-webdriver'

caps = Selenium::WebDriver::Remote::Capabilities.internet_explorer(:javascript_enabled => true)
driver = Selenium::WebDriver.for(:remote, :url => "http://92.168.0.1:4444/wd/hub", :desired_capabilities => caps)
driver.get "http://www.yahoo.co.jp"

wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
begin
    element = wait.until { driver.find_element(:id => "some-dynamic-element") }
ensure
    driver.quit
end


遭遇したエラー達
上記のサンプルプログラムを実行しようとすると、Firefoxの起動が出来るもののIEの場合はエラーが出るという現象に遭遇しました。

$ ruby ie.rb
[remote server] org.openqa.grid.web.servlet.handler.RequestHandler(RequestHandler.java):151:in `process': Error forwarding the new session cannot find : {platform=WINDOWS, javascriptEnabled=false, cssSelectorsEnabled=true, browserName=internet explorer, nativeEvents=false, rotatable=false, takesScreenshot=true, version=} (org.openqa.grid.common.exception.GridException) (Selenium::WebDriver::Error::UnknownError)
        from [remote server] org.openqa.grid.web.servlet.DriverServlet(DriverServlet.java):81:in `process'
        from [remote server] org.openqa.grid.web.servlet.DriverServlet(DriverServlet.java):67:in `doPost'
        from [remote server] javax.servlet.http.HttpServlet(HttpServlet.java):727:in `service'
        from [remote server] javax.servlet.http.HttpServlet(HttpServlet.java):820:in `service'
        from [remote server] org.openqa.jetty.jetty.servlet.ServletHolder(ServletHolder.java):428:in `handle'
        from [remote server] org.openqa.jetty.jetty.servlet.WebApplicationHandler(WebApplicationHandler.java):473:in `dispatch'
        from [remote server] org.openqa.jetty.jetty.servlet.ServletHandler(ServletHandler.java):568:in `handle'
        from [remote server] org.openqa.jetty.http.HttpContext(HttpContext.java):1530:in `handle'
        from [remote server] org.openqa.jetty.jetty.servlet.WebApplicationContext(WebApplicationContext.java):633:in `handle'
        from [remote server] org.openqa.jetty.http.HttpContext(HttpContext.java):1482:in `handle'
        from [remote server] org.openqa.jetty.http.HttpServer(HttpServer.java):909:in `service'
        from [remote server] org.openqa.jetty.http.HttpConnection(HttpConnection.java):820:in `service'
        from [remote server] org.openqa.jetty.http.HttpConnection(HttpConnection.java):986:in `handleNext'
        from [remote server] org.openqa.jetty.http.HttpConnection(HttpConnection.java):837:in `handle'
        from [remote server] org.openqa.jetty.http.SocketListener(SocketListener.java):243:in `handleConnection'
        from [remote server] org.openqa.jetty.util.ThreadedServer(ThreadedServer.java):357:in `handle'
        from [remote server] org.openqa.jetty.util.ThreadPool$PoolThread(ThreadPool.java):534:in `run'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/remote/response.rb:50:in `assert_ok'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/remote/response.rb:15:in `initialize'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/remote/http/common.rb:58:in `new'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/remote/http/common.rb:58:in `create_response'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/remote/http/default.rb:64:in `request'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/remote/http/common.rb:39:in `call'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/remote/bridge.rb:450:in `raw_execute'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/remote/bridge.rb:92:in `create_session'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/remote/bridge.rb:68:in `initialize'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/common/driver.rb:33:in `new'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver/common/driver.rb:33:in `for'
        from /usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.15.0/lib/selenium/webdriver.rb:60:in `for'
        from ie.rb:5

原因としては、クライアント側の起動を次のように単なるノードとして起動していました。これは、Selenium 1.0時代の起動です。-role webdriverで解決です。色々探っていても1.0系の情報が多くて、結構混乱するんですよね。

java -jar selenium-server-standalone-2.14.0.jar -role node  -hub http://localhost:4444/grid/register

まとめ


  • これから使うならSelenium 2.0
  • でもSelenium 1.0の情報が多くて、混乱して大変。
  • みんなでSelenium 2.0の情報を共有していこう


enjoy!!


See Also:
Web画面の自動テストの導入に失敗する理由とその対策
JenkinsとSelenium WebDriverでUI層のテストも自動化&永続化する
ユニットテストのデータ生成は、FixtureよりFactoryモデル