Seleniumは、Webブラウザのテストを自動化するためのツールです。Webブラウザにアタッチし、あらかじめ定義されたテストを自動的に実行し、結果を出力します。Webアプリケーションの動作確認のほか、ウィンドウサイズの変更やリンク切れの確認やスクリーンショットのキャプチャを実行できます。デザインやJavaScriptコードを包括的に担当する、Webクリエイターのための必携ツールと言えるでしょう。

Selenium WebDriverを使ったテストの自動化

Seleniumは、Webブラウザのテストを自動化するためのツールです。Webブラウザにアタッチし、クリックやスクロール・文字入力などを始めとして、あらかじめ定義されたテストを自動的に実行します。

Seleniumはもともと、Firefoxのアドオンとして提供されていました。今日ではSelenium WebDriverと呼ばれる、Webブラウザを外部プログラムから操作するための機構が備わっています。より複雑なテストケースを、自分の好みの言語(Java, C#, Ruby, Python, JavaScriptなど)で記述し、いままでブラウザ上で手動でおこなっていた操作を自動化できるようになりました。

Seleniumを使ったテストをおこなう際に必要になるソフトウェアは、次のとおりです。

機能の名前 概要
Selenium Server Selenium本体です。Javaで記述されています。
Selenium WebDriver Webアプリケーションのテストツールです。JavaやPythonなどの言語で、テストを記述します。もともとはGoogleが「WebDriver」として開発を進めていましたが、その後「Selenium」プロジェクトと合流した経緯があります。SeleniumHQがメンテナンスしている言語は、Java、C#、Ruby、Python、JavaScriptの5種類です。このほか、サードパーティが開発しているWebDriver向けの言語セットとしてPerl, PHP, Haskellなどがあります。
Browser Driver SeleniumがWebブラウザを操作して、テストをおこなうためのドライバソフトウェアです。サードパーティが開発しているドライバとして、Google Chrome, Opera, iOS向けのドライバなどが公開されています。

Selenium ServerはJavaで記述されており、実行にはJavaの実行環境とJAVA_HOMEなどの環境変数の設定が事前に必要になります。Seleniumを利用する前に、あらかじめJavaの実行環境を準備する必要があります。

ここでの動作環境は次のとおりです。

・OS: Windows 7
・Java: 1.7.0_25
・Google Chrome: 30.0.1599.101 m

なお、SeleniumのテストケースはJavaScript(node.js)を用いるものとします。

Selenium Serverのインストール

ダウンロードページにアクセスし、Selenium Serverをダウンロードします。執筆時点での最新バージョンは2.37.0です。

selenium-server-standalone-2.37.0.jarをダウンロードし、Cドライブ直下に配置しました。

Selenium Clientのインストール - node.js / selenium-webdriver

node.jsのダウンロードページより、Windows Installer (.msi) をインストールします。執筆時点での最新バージョンは、node-v0.10.21-x86.msiです。

インストーラをダウンロード後、起動してNode.jsのインストールをおこないます。

Node.jsインストール後、コマンドプロンプトでNode Packaged Modules(以降、npmと表記)が利用できるようにPATH環境変数とNODE_PATH環境変数を設定します。システムのプロパティより、それぞれの環境変数に次の値を設定・追加します。

PATH C:\Program Files\nodejs\
NODE_PATH C:\Users\(ユーザ名)\AppData\Roaming\npm\node_modules

環境変数の設定後、コマンドプロンプトでnpmが利用できるようになります。

続けて、selenium-webdriverをインストールします。コマンドプロンプト上で、先ほどインストールしたnpmを使用してselenium-webdriverとmochaをインストールします。

npm -g install selenium-webdriver
npm -g install mocha

Seleinum Google Chrome Driverのインストール

ダウンロードページにアクセスし、最新のSelenium Google Chrome Driverをダウンロードします。

執筆時点での最新バージョンは2013-11-06に公開された、Version 2.6です。ここでは、chromedriver_win32.zip (md5: 48f8d2462e44b8d06f88ff56857620c0)をダウンロードしました。

ダウンロードしたZipパッケージを解凍します。Cドライブ直下に"chromedriver_win32"フォルダを作成し、フォルダ内に配置しました。

Seleinum Serverの起動

Selenium Serverを起動します。コマンドプロンプトで、Cドライブ直下に移動して次のコマンドを実行します。

java -jar selenium-server-standalone-2.37.0.jar -Dwebdriver.chrome.driver=C:\chromedriver_win32\chromedriver.exe

上記の操作で、Selenium Serverが起動しました。開発者はSelenium Serverに対して、任意の言語で記述したテストケースを渡します。Selenium ServerはWebブラウザに接続して、テストケースを自動的に実行する流れになります。Selenium Serverを止める場合は、Selenium Serverを実行しているコマンドプロンプト上で Ctrl-C を押下します。

Selenium WebDriverを利用したテストの自動化

JavaScriptを用いて、Seleniumのテストケースを記述してみましょう。

ファイル名: test1.js

var webdriver = require('selenium-webdriver');

var driver = new webdriver.Builder().
usingServer('http://localhost:4444/wd/hub').
withCapabilities(webdriver.Capabilities.chrome()).
build();

driver.get('http://creator.mynavi-agent.jp/');

driver.quit();

このテストケースでは、次の処理をおこないます。

  1. Google Chromeを起動
  2. マイナビクリエイターのサイトにアクセス
  3. Google Chromeを終了
  4. コマンドプロンプトで、test1.jsが格納されているディレクトリに移動し、次のコマンドを実行します。

    node test1.js

コマンドを実行するとGoogle Chromeが起動し、マイナビクリエイターのサイトが表示されます。表示完了後、Google Chromeは自動的に終了します。

今度はもう少し複雑なテストケースを作成してみましょう。

ファイル名: test2.js

var webdriver = require('selenium-webdriver');
var fs = require('fs');

var driver = new webdriver.Builder().
    usingServer('http://localhost:4444/wd/hub').
    withCapabilities(webdriver.Capabilities.chrome()).
    build();

var url =
[
    'http://creator.mynavi-agent.jp/',
    'http://creator.mynavi-agent.jp/jinzai/feature/toolbox/index.html'
]

webdriver.WebDriver.prototype.saveScreenshot = function(filename) 
{
    filename = filename.replace('|' , '_');
    return driver.takeScreenshot().
    then(function(data)
    {
        fs.writeFile
        (
            filename,
            data.replace(/^data:image\/png;base64,/,''), 
            'base64',
            function(error)
            {
                if(error) throw error;
            }
        );
    });
};

function sleep(milliSeconds)
{
    var startTime = new Date().getTime();
    while (new Date().getTime() < startTime + milliSeconds);
}

url.forEach
(
    function(uri)
    {
    var fileName = '';
    driver.get(uri).
        then(function()
        {
            return driver.getTitle();
        }).
        then(function(title)
        {
            fileName = title;
        }).
        then(function()
        {
            return driver.manage().window().maximize();
        }).
        then(function()
        {
            sleep(500);
            return driver.saveScreenshot( fileName + '_max.png');
        }).
        then(function()
        {
            return driver.manage().window().setSize(1024, 768); 
        }).
        then(function()
        {
            sleep(500);
            return driver.saveScreenshot( fileName + '_1024x768.png');
        }).
        then(function()
        {
            return driver.manage().window().setSize(640, 360); 
        }).
        then(function()
        {
            sleep(500);
            return driver.saveScreenshot( fileName + '_640x360.png');
        }).
        then(function()
        {
            return driver.manage().window().setSize(320, 480); 
        }).
        then(function()
        {
            sleep(500);
            return driver.saveScreenshot( fileName + '_320x480.png');
        });
    }
);
driver.quit();

このJavaScriptコードでは、配列に定義したURLに順にアクセスし、それぞれのウィンドウサイズの条件でのスクリーンショットをキャプチャ、PNG画像として保存します。スクリーンショットが崩れないよう、ウィンドウサイズを変更した後に、遅延処理を入れています。

var url =
[
    'http://creator.mynavi-agent.jp/',
    'http://creator.mynavi-agent.jp/jinzai/feature/toolbox/index.html'
]

先頭においてURLの配列を定義します。ここではマイナビクリエイターのサイトと、本連載の記事一覧ページを指定しています。

webdriver.WebDriver.prototype.saveScreenshot = function(filename) 
{
    filename = filename.replace('|' , '_');
    return driver.takeScreenshot().
    then(function(data)
    {
        fs.writeFile
        (
            filename,
            data.replace(/^data:image\/png;base64,/,''), 
            'base64',
            function(error)
            {
                if(error) throw error;
            }
        );
    });
};

コード冒頭でprototypeを用いて、saveScreenshotメソッドを定義します。saveScreenshotメソッドでは、ファイル名を受け取り、Webブラウザ内に表示されている内容のスクリーンショットをキャプチャします。キャプチャ後、ファイル名を使用してファイルシステム上にPNG形式の画像ファイルを作成します。

url.forEach
(
    function(uri)
    {
    var fileName = '';
    driver.get(uri).
        then(function()
        {
            return driver.getTitle();
        }).
        then(function(title)
        {
            fileName = title;
        }).
        then(function()
        {
            return driver.manage().window().maximize();
        }).
        then(function()
        {
            sleep(500);
            return driver.saveScreenshot( fileName + '_max.png');
        }).
        then(function()
        {
            return driver.manage().window().setSize(1024, 768); 
        }).
        then(function()
        {
            sleep(500);
            return driver.saveScreenshot( fileName + '_1024x768.png');
        }).
        then(function()
        {
            return driver.manage().window().setSize(640, 360); 
        }).
        then(function()
        {
            sleep(500);
            return driver.saveScreenshot( fileName + '_640x360.png');
        }).
        then(function()
        {
            return driver.manage().window().setSize(320, 480); 
        }).
        then(function()
        {
            sleep(500);
            return driver.saveScreenshot( fileName + '_320x480.png');
        });
    }
);
driver.quit();

JavaScriptのforEachを使用して、先頭にて指定したURLにアクセス、ページのタイトルを取得します。その後、ウィンドウサイズを最大化 → 1024x768 → 640x360 → 320x480 の順に変更し、それぞれのスクリーンショットをキャプチャします。スクリーンショットのファイル名には、ページのタイトルを用います。

node.jsやSelenium-WebDriverの詳しい記法については、各種ドキュメントをご参照ください。

Node.js Manual & Documentation
WebDriverJs - selenium - A guide to using the JavaScript bindings for WebDriver.
Index

ファイルを保存後、コマンドプロンプトで、次のコマンドを実行します。

node test2.js

Google Chromeを起動すると、マイナビクリエイターのサイトが表示されます。自動的にウィンドウサイズが変更され、スクリーンショットがPNG画像形式で保存されます。

4種類の画像をキャプチャ後、続いてクリエイターの道具箱の記事一覧が表示されます。同様に自動的にウィンドウサイズが変更され、スクリーンショットがキャプチャされます。キャプチャ終了後、Google Chromeが自動的に終了します。

Selenium WebDriverを活用すれば、手動でおこなっていたWebページ内の各種リンク切れの調査や、レスポンシブWebデザインに対応したWebサイトの表示確認等の作業を自動化できます。テストケースを充実させれば、開発 → 確認 → 修正のサイクルをより省力化できることでしょう。

これまでに紹介したRedmineといったチケットトラッキングやバージョン管理システムも併用して、品質の高いWebサイト/Webアプリケーションを開発していきましょう。

富田宏昭 Hiroaki Tomida
「株式会社キクミミ」でFileMakerやオープンソース言語などを用いた、Webアプリ開発 企業の業務改善のためのシステム開発や環境構築を行っている。主な著書に「HTML5/JavaScriptとPhoneGapで作るiPhoneアプリ開発入門」(マイナビ)など。