入門、Selenium 第1回 Seleniumの仕組み

ブラウザのオートメーションツール、Seleniumについて解説します。第1回では、Sleniumの基本的な仕組みや、用語を取り上げます。ツールをインストールし、実際に動かしてみましょう。

発行

著者 外村 和仁 フロントエンド・エンジニア
入門、Selenium シリーズの記事一覧

2014年の記事です。記事中で紹介されている環境とコードでは、現在動作しません。

はじめに

Selenium(セレニウム)はブラウザのオートメーションツールです。自動でブラウザを操作することでWebサイトの動作のテストを行うことができます。本シリーズではSeleniumの仕組みや基本的な使い方、Seleniumを使ったテストの記述方法などについて解説します。

初回である今回は、Seleniumの基本的な仕組みについて解説します。

Selenium RCとWebDriver

Seleniumには旧APIであるSelenium RC(Remote Control)と、新しいAPIのSelenium WebDriverがあります。それぞれ、Selenium1、Selenium2と呼ばれることもあります。

Selenium RCはJavaやPythonなどの言語で書いたスクリプトを元に、ブラウザを操作するためのJavaScriptを生成し、対象のページにそのJavaScriptを埋め込んでブラウザを操作するという仕組みでした。

しかし、Selenium RCはJavaScriptのコードを対象のページに埋め込んでブラウザを自動的に操作するという仕組み上、セキュリティの制限を受けるなどの欠点がありました。

その問題点を解決するために、ブラウザの拡張機能やOSのネイティブ機能などを利用してブラウザを操作する仕組みがSelenium WebDriverです。元々はWebDriverという名前で開発されていましたが、Seleniumと統合されSelenium WebDriverという名前になりました。

今でもSelenium RCの機能は利用可能ですが、Selenium3のロードマップではSelenium RCの機能は非推奨となり開発を凍結し、今後はWebDriverのAPIの開発を進めていくことが発表されています。

また、WebDriverのAPIはW3Cで標準化が進められています。

WebDriver(執筆現在:2014年11月14日編集者草案)

今回の連載では主にこのSelenium WebDriverについて解説していきます。

Selenium WebDriverのアーキテクチャ

まずはSelenium WebDriverがどのような仕組みでブラウザの自動操作を行うのかを解説します。

Selenium WebDriverは各種ブラウザごとにドライバが用意されています。それらのドライバはJSON Wire ProtocolというSeleniumが定義しているRESTful API*に対応しており、このAPIにしたがってリクエストすることでブラウザを操作することができます。

*注:RESTful API

RESTとはRepresentational State Transferの略で、リソースにURLで名前を付け、HTTPメソッド(GET、POST、PUT、DELETEなど)で操作するという考え方です。そのようなAPI全般を総称してRESTful APIと呼びます。

各ドライバによって形式やブラウザを操作する方法はさまざまです。FirefoxドライバはFirefoxの拡張機能として用意されていますし、Chromeドライバは実行ファイル(バイナリ)で提供されています。

Selenium WebDriverのアーキテクチャを理解するために、ライブラリを使わずにブラウザの操作をしてみましょう。起動が簡単なChrome Driverを利用します。まずは以下から自分の環境にあったzipファイルをダウンロードします*。

*注:Chrome Driverのインストール

OS Xでhomebrewを使っている場合はbrew install chromedriverでもインストールできます。その場合はchromedriverコマンドで起動できます。

http://chromedriver.storage.googleapis.com/index.html

zipファイルを解凍すると実行ファイルが得られるので、そのファイルをコマンドラインから実行します。例えばOS Xだとchromedriverというファイルが得られるので、解凍したディレクトリにcdで移動して次のようにします。

$ ./chromedriver

そうすると9515番ポートでドライバが起動します。まずは新規セッションを作成し、ブラウザを立ち上げるためにJSON Wire ProtocolのPOST /sessionに従ってHTTPリクエストを発行します。別タブなどで、もうひとつシェルを起動して以下のコマンドでリクエストします。

$ curl -X POST \
       -H "Content-Type: application/json" \
       -d '{"desiredCapabilities":{"browser":"chrome"}}' \
       http://localhost:9515/session

curlコマンドはHTTPリクエストを行うためのコマンドで、OS Xであればデフォルトでインストールされています。

ここではSelenium WebDriverのアーキテクチャを知るためにコマンドラインからHTTPリクエストをするという冗長なことを行っていますが、実際には各言語のライブラリが使いやすいインターフェースを提供してくれるので、Seleniumを使うにあたってこのコマンドを覚える必要は一切ありません。

上記コマンドが成功するとChromeのウィンドウが新しく開き、次のようなレスポンスがターミナルに返ってくるはずです(実際のレスポンスは1行ですが、見やすいように整形しています)。

{
  "sessionId": "a433343ec6e678b1bc17a93bbbf6aea7",
  "status": 0,
  "value": {
    "acceptSslCerts": true,
    "applicationCacheEnabled": false,
    "browserConnectionEnabled": false,
    "browserName": "chrome",
    "chrome": {
      "userDataDir": "/var/folders/p6/ll1grbcs4jv_k7675qv47l6m0000gn/T/.org.chromium.Chromium.wEZRL6"
    },
    "cssSelectorsEnabled": true,
    "databaseEnabled": false,
    "handlesAlerts": true,
    "javascriptEnabled": true,
    "locationContextEnabled": true,
    "nativeEvents": true,
    "platform": "Mac OS X",
    "rotatable": false,
    "takesHeapSnapshot": true,
    "takesScreenshot": true,
    "version": "38.0.2125.111",
    "webStorageEnabled": true
  }
}

このレスポンスに含まれるsessionIdを使って、今開いたブラウザを操作できます。例えばURLを指定して特定のページを開いてみましょう。

JSON Wire ProtocolのPOST /session/:sessionId/urlを利用します。

$ curl -X POST \
       -H "Content-Type: application/json" \
       -d '{"url":"http://www.pxgrid.com/"}' \
       http://localhost:9515/session/a433343ec6e678b1bc17a93bbbf6aea7/url

*注:sessionId

a433343ec6e678b1bc17a93bbbf6aea7の部分は、先ほどのsession作成時に取得したsessionIdを適宜入れてください。

これでピクセルグリッドのサイトに遷移すれば成功です。このように、Selenium WebDriverはJSON Wire ProtocolというRESTful APIを利用してブラウザを自動的に操作します。

クライアントライブラリ

ブラウザのドライバに対して、JSON Wire ProtocolでHTTPリクエストを行うとブラウザが操作できることはわかりました。

実際にSelenium WebDriverを使う場合、先ほどの例のように、自分でHTTPリクエストを作成して操作するということはなく、これらのAPIを扱うためのクライアントが用意されています。現在Seleniumが公式で提供しているクライアントライブラリは次の言語です。

例えばNode.jsの公式ライブラリであるselenium-webdriverを利用してみましょう。selenium-webdriverはnpmでインストールできます。

$ npm install selenium-webdriver

launch_firefox.jsという名前で次のように記述し実行します。

var firefox = require('selenium-webdriver/firefox');
var driver = new firefox.Driver();
driver.get('http://www.pxgrid.com/');
$ node launch_firefox.js

これでFirefoxが立ち上がってピクセルグリッドのサイトに遷移し、すぐにブラウザが閉じれば成功です。npmのselenium-webdriverはFirefoxのドライバを同梱しているので、自前でドライバを準備する必要がありません。ChromeやIEなどのドライバは同梱されていませんので、自分でダウンロードしてパスが通っているところに設置する必要があります。

また、先ほどのChromeドライバをcurlコマンドで動かした際には、chromedriverのサーバーを起動し、そのサーバーに対してリクエストを行いましたが、ここではドライバを起動していません。これはライブラリがドライバの起動も同時にやってくれているからです。

コラム:Selenium IDEとSelenium Builder

Selenium IDEはFirefoxの拡張機能としてインストールでき、ブラウザ上で要素を選択するなどしてSeleniumのテストを記述できるツールです。SeleniumというとSelenium IDEのイメージが強い方もいるかもしれません。

Selenium IDEはSelenium RCの機能しか利用できないという理由から、最近ではSelenium Builderという、Selenium WebDriverの機能を利用できるGUIツールの開発が活発です。こちらもSelenium IDEと同じくFirefoxの拡張機能としてインストールできます。

今回のシリーズではこれらのGUIツールの使い方について解説しませんが、GUIを使ったSeleniumの利用を検討している方はSelenium Builderも検討してみるといいかもしれません。

Selenium Server

公式で用意されているライブラリのほとんどはドライバを自動で起動する機能を持っていますが、特定のドライバに対応してないライブラリもあります。例えば上記で利用したNode.jsの公式ライブラリは現在のバージョン(2.44.0)で対応しているのはFirefoxとChromeのみです。ドライバに対応していないブラウザを操作するにはSelenium Serverを利用します。

Selenium ServerはJavaで書かれたサーバーで、クライアントとドライバの中継サーバーとして振る舞うので、クライアントライブラリがドライバの管理をする必要がなくなります。

また、公式でライブラリが用意されていない言語(PHP、Perl、Goなど)ではサードパーティのクライアントが多数公開されていますが、それらはSelenium Serverの利用を前提としているケースが多いようです。

Selenium Serverとドライバは当然JSON Wire Protocolで通信しますが、クライアントとSelenium Server同士もJSON Wire Protocolでリクエストを行います。リクエストを受け取ったSelenium Serverは適切なブラウザのドライバを起動して、ドライバにリクエストを行います。

Selenium Serverはダウンロードページからselenium-server-standalone-xxx.jarxxxはバージョン番号)というファイルをダウンロードでき、次のコマンドで起動できます*。

$ java -jar selenium-server-standalone-xxx.jar

*注:Selenium Serverのインストール

OS Xでhomebrewを使っている場合はbrew install selenium-server-standaloneでもインストールできます。その場合はselenium-serverコマンドで起動できます。

Selenium ServerはほかにもSelenium RCのコマンドをSelenium WebDriverで実行したり、複数のサーバーで同時にテストを行うためのGridという機能も持っていますが、それらについては今回のシリーズでは触れません。

まとめ

今回はSeleniumの用語の整理や、Selenium WebDriverのアーキテクチャについて解説しました。実際にSeleniumを利用する上で必ず知っておかないと困るという知識ではありませんが、このようなことを知った上でSeleniumを利用すると、より理解が増すと思います。

次回は実際にブラウザを操作してテストを行うプログラムを書いていきます。