各Webブラウザで実装されている開発者向けの機能を紹介しています。これまでGoogle Chrome、Firefoxについて紹介してきましたが、今回はMac OSX用のSafariについて紹介します。
DOMを確認するのに使えるインスペクタ
DOMやスタイルの状態を確認するのに便利なのがインスペクタです。

適用されているCSSのスタイル設定についても確認できます。

スタイルを追加する場合には入力補完がきいています。

現在表示しているURLだけでなく、iframeなどで埋め込まれたURLについても解析できます。

JavaScript/CSSの内容を確認できるリソース
インスペクタでJavaScriptファイルなどをクリックするとリソースタブに飛びます。ソースの確認ができるほか、ブレークポイントの設定もできます。

単純にソースを表示する以外にもアクセス時のHTTPヘッダーなど詳細な情報も確認できます。

読み込みにかかった時間がわかるネットワーク
ネットワークタブでは読み込んだリソースに関するサイズ、レイテンシ、転送時間など細かな情報が確認できます。

各リソースをクリックするとインスペクタまたはリソースタブが表示されます。
処理にかかった時間がわかるタイムライン
ネットワーク、レンダリング、JavaScriptなど各処理にかかった時間を計測してグラフ化するのがタイムラインです。

サイトの表示に時間がかかる、またはさらに最適化したいといった時に役立つでしょう。
ローカルストレージ、キャッシュ状態を確認するのにストレージ
ストレージタブではCookie、セッションストレージ、ローカルストレージなどの情報が確認できます。表形式で確認できるのでわかりやすいと思います。

フロントエンド開発の基本と、コンソール
コンソール機能は他のブラウザと変わらず便利に使えるはずです。

セキュリティ上の制限が他のブラウザに比べると厳しいようで、エラーメッセージが多いのが気になります(特にソーシャルボタンでのエラーが多いようです)。
スニペットエディタがあり、そこでちょっとしたコードを書いておくことができます。

iOSでのWebサイトデバッグでは必須
Safariの最大の利点はiOSデバイスを接続してSafari for iOSのデバッグに利用できることでしょう。一部のハイブリッドアプリであれば同様にデバッグができます。

Safariの開発者向けの向け機能は他のブラウザに比べるとあまり多機能ではないようです。とはいえMac OSXのデフォルトではブラウザとあって、そのまま使っているだけなのでユーザも相当数います。そして、意外とSafariでは動かないJavaScriptを見かけることが多いです。
Safariで動かない原因を調べるにはやはりSafariを使った方が良いでしょう。スマートフォン対応も踏まえ、Safariを使った開発、デバッグ方法の習得は必要そうです。
去る12月09日、渋谷で行われたOSC(オープンソース・カンファレンス) 2015 .Enterprise 東京に参加しました。多数の方にブースへお越しいただき、hifiveを紹介できました。

今回はhifiveとともにPitaliumに関しても展示しています。
通常のOSCと異なり、スーツを着ている方が多く(来場者、出展者ともに)、hifiveのターゲットでもある企業向けのカンファレンスであるといった雰囲気が出ています。とはいえ、オープンソースなので開発者の方が多かったようです。

今回が2015年最後のオープンソース・カンファレンスになります。今年は初のOSC参加で、東京、名古屋、札幌、福岡、沖縄、関西と参加してきましたが、それぞれに特色があり、楽しいカンファレンスでした。皆さんはどの会場に参加されましたか?

前回のGoogle Chrome DevToolsに続いて、今回はFirefoxの提供する開発ツールについて見ていきます。元々この手のツールが注目を浴びたのはFirefoxアドオンだったFirebugが最初だったのではないでしょうか。それもあってかFirefoxの提供する開発者ツールは細かい点まで気が配られた、とても使い勝手の良い機能となっています。
Firefox Developer Edition — Mozilla
Firefoxの種類について
Firefoxには2つの種類があります。一つは一般ユーザ向けのFirefoxで、もう一つはWeb開発者をターゲットにしたFirefox Developer Editionになります。Firefox Developer Editionは標準のFirefoxをベースに、開発に役立つアドオンがインストールされているものになります。今回はそのFirefox Developer Editionをベースにしていきます。
開発ツールの起動
開発ツールはツールメニューまたはWindows/LinuxであればCtrl + Shift + I、Mac OSXではコマンド + Opt + Iで起動します。開発ツールは実に多機能で、設定から表示するタブを切り替えられるくらいです。

UIの設計、確認が容易なインスペクタ
まず基本となるインスペクタです。DOM構造やスタイル設定などが確認できます。

該当部分のDOMはハイライト表示されるのでわかりやすいです。

スタイルを一時的に変更して表示確認もできます。

HTMLについても編集できます。

スタイルの変更などはその場で反映されます。

JavaScriptのデバッグ、確認に便利なコンソール
こちらもインスペクタ同様によく使われる機能だと思います。

補完も行われるので便利です。ちょっとしたコードを試したり、変数の状態を調べるのに使えます。

さらにユニークな機能としてファイルの切り替えがあります。iframeで読み込まれているソーシャルボタンなど、外部サイトの解析を行う際に対象ファイルを切り替えることができます。

もちろんスマートフォン向けの画面サイズで確認するといったシミュレーション機能もあります。

JavaScriptのデバッグに使えるデバッガ
読み込まれているコードのデバッグに使うのはデバッガタブです。

ブレークポイントを設定したり、ウォッチを入れることができます。同時にコンソールを使うこともできます。

スタイルシートの設定を確認するのに使えるとスタイルエディタ
インスペクタではマウスを当てたDOMのスタイルを確認する方法でしたが、スタイルエディタでは個々のファイルに対する全体の設定を確認できます。ここで修正した内容はそのまま反映されますし、保存ボタンを押してダウンロードすることもできます。

HTML/JavaScriptのパフォーマンスチェックにPerformance
Performanceタブはそのままで、Webアプリケーション全体のパフォーマンスをチェックできます。

DOMイベントにかかった時間を見たり、JavaScriptで時間のかかっている処理を確認するのが便利です。グラフで見たり、一覧表で確認することもできます。

JavaScriptについてだけ掘り下げてみることもできます。

通信内容を確認するネットワーク
ネットワークタブでは接続した情報を確認できます。

ヘッダ情報などを編集してその場で再実行できる機能が便利です。

テキストエリアを使って内容を編集したり、コピーして別なツールで使ったりするのもよくあるニーズと言えそうです。

Canvas処理の内容を確認
Firefoxだけではないかと思われる機能がCanvasの解析です。今後アニメーションコンテンツが増えていく中でかなり役立つのではないでしょうか。

細かく処理を追いかけられるようになっています。

Web Audioにも対応
他にもWeb Audioについてもビジュアル化させることができます。開発ツール上からプロパティの値を変更して、ピッチを変えたりすることができます。

ストレージの中身をビジュアル化
ストレージタブを使えばCookie、セッションストレージ、IndexedDBなどの値を表形式で閲覧できます。

開発ツールの使い方を学べる
Firefox Developer EditionのサイトではDevTools Challengerというコンテンツを用意しています。これは深海へ潜行していくのを通じて開発ツールの使い方を学んでいくコンテンツです。

やるべきミッションが書かれていますので、それをこなすとさらに潜行(スクロールしていく)といったゲーム形式で開発ツールの使い方を習得できるようになっています。

こんな感じでアニメーション速度をビジュアル的に変えられる、なんてマニアックな機能も覚えられます。

コンテンツは英語ですが、そんなに難しい言葉はありませんし、動画をみて操作を確認できます。Firefoxの開発ツールでどんなことができるのか、まずはDevTools Challengerを使って覚えるのがお勧めです。
Firefox Developer Editionは開発者向けとあって、多くの開発時に役立つのでは機能が用意されています。他にもWeb IDE(まだIDEと呼ぶには機能不足感はありますが)もあり、Web開発を行う方にとって強力なツールになるのではないでしょうか。
フロントエンド開発において欠かせない存在になっているのがWebブラウザに付随する開発者ツールです。Google Chrome、Firefox、Safari、IEと各ブラウザに実装されていますが、その使い勝手や機能は細かく違っています。
そこで各ブラウザにおける操作性や機能の違いを掘り下げて紹介します。最初になる今回は最も利用者が多いと思われるGoogle Chromeです。
Google Chromeにおける開発者用ツール「DevTools」
Google Chromeやその元になるChromiumではDeveloper ToolsまたはDevToolsと呼ばれています。F12を押すと呼び出されます。
多機能かつ使いやすさとしては逸品ではないでしょうか。
機能はタブに分かれており、
- Elements
- Network
- Sources
- Profiles
- Resources
- Audits
- Console
に分かれています。まず各タブの機能を紹介します。
HTML、スタイルシートを確認できるElements
ElementsタブではHTMLソースの確認やスタイルシートの状態を確認できます。ソースは単にサーバから受け取ったものではなく、その後のJavaScriptによる操作も反映した状態が確認できます。
さらにHTMLを編集したり、要素のCSSパスやXPathでコピーもできます。これを使うことでJavaScriptから操作するDOMの指定が簡単に分かるようになります。
スタイルの設定はどのスタイルシートファイルなのか一目で分かりますし、設定が適用されているかどうかも分かります。適用されていない(そもそもサポートされていない、または上書きされている)場合は打ち消し線が表示されているのですぐに分かります。また、スタイルの設定を追加、編集、外す(チェックボックスを外す)指定も行えます。

HTMLも変更できます。


ただしHTMLの変更やスタイルシートの編集やあくまでもWebブラウザ上だけのものになりますので実際のファイルへは反映されません。再読込すると元に戻ってしまうのでご注意ください。
他にもイベントリスナーの一覧を確認することもできます。ただしこれは実際にaddEventListnerを設定したメソッドが呼ばれるので、jQueryなどのラッピングしてくれるライブラリを使っている場合は処理を追いかけるのは難しいかも知れません。

リソースの読み込み状態を確認できるNetwork
NetworkタブではWebサイトを表示するのに使われている各リソースのダウンロード時間を確認することができます。Webページの表示に時間がかかっている場合、ここでチェックすることで全体の表示にかかっている時間を確認することができます。

JavaScriptのダウンロードにかかる時間であったり、さらにそこから動的に読み込まれるスクリプト群の時間、各種画像など計測してみるとどれくらい時間がかかっているのか一目で分かるようになります。
さらにタイミングごとのスクリーンショットを撮ってくれる機能があります。これを見るとWebサイトの読み込みが完了するまでの表示(大抵崩れていたりするものです)を確認できます。

ネットワーク速度を変える機能があります。一番遅い場合で50KB/sまで落とすことができます。モバイルでの表示速度を確認したり、オフライン時の表示を確認するのに便利です。

ネットワークはプロファイルが多数登録されています。これは自作可能です。

各種リソースの確認ができるSources
Sourcesタブではページを表示する際に読み込んでいる各種コンテンツをツリービューで確認できます。HTML/JavaScript/CSSファイルの他、画像やWeb Fontなども確認できます。HTMLやJavaScriptファイルに対してブレークポイントを差し込むこともできます。これはデバッグではよく使われる機能ですね。

実際にブレークポイントに来た時は行がハイライト表示されます。

マウスオーバーでその値を確認できます。

ウォッチも用意されていますので逐次変化していく値を追いかけることもできます。JavaScriptは変数がすぐにグローバルになってしまうのでウォッチが役立つでしょう。

スタイルシートの内容確認もできます。

Sourcesの中にはスニペット機能もあります。ここによく使う開発用便利スクリプトを残しておくと使い回しができて便利です。

処理にかかっている時間を細かく確認できるTimeline
Timelineタブでは各種処理時間をレコーディングしてグラフ化します。

主にローディング、スクリプト、レンダリング、描画、その他となっています。メモリに関する測定もできます。

CPU/メモリの解析ができるProfiles
ProfilesタブではCPUやメモリのプロファイルができます。

全体の処理について、どこで遅延が発生しているか、メモリが使われているかなどを測定するのに役立ちます。ハイパフォーマンスを求める場合は必須の機能でしょう。
ストレージ、Cookiesの状態が分かるResources
かつてはCookieくらいだったのが、HTML5になって多くのデータがWebブラウザ内部に蓄積できるようになっています。それが可視化されるのがResourcesタブです。

Web SQL、IndexedDB、LocalStorage、Session Storage、Cookies、Application Cache、Cache Storageについてデータを一覧で確認できます。

Webサイトの高速化に関するレポートを出力するAudit
Webサイトにおける改善ポイントを指摘くれるのがAuditタブです。外部JavaScriptファイルに関する指摘や、ブラウザキャッシュ、スタイルシートやJavaScriptの並び順最適化など多くの項目に関してレポーティングします。

開発の基本ともいえるConsole
ConsoleタブはWebアプリケーション開発における基本とも言えるタブです。制限されている変数に対する補完も行われるので効率的なデバッグができます。

関数の中身も確認できます。ただしここからブレークポイントを仕込むことはできません。

その他の機能
その他の機能として、スマートフォンやタブレットの画面サイズをエミュレートする機能があります。

デバイス名を選ぶだけでサイズを設定してくれるのが便利です。

設定ではレンダリングにおける指定ができます。FPS表示はWebゲーム開発で役立つでしょう。

検索機能も便利で、HTML/JavaScript/CSSファイルを縦断的に検索してくれます。正規表現も使えます。

USBをつないで外部デバイスのデバッグにDevToolsを使うこともできます。

各種プラグインによる拡張もサポート
DevToolsはプラグインで拡張ができます。例えばPHPのデバッグメッセージをChromeで受けられるPHP Console、Ruby on RailsであればRailsPanel、Django向けにはDjango Debug Panel、React向けのReact Developer Toolsなどがあります。こうした機能拡張を組み合わせることでより効率的な開発体制ができるはずです。
Google ChromeのDevToolsはHTML5フロントエンド開発において充実した機能を備えています。ぜひ多くの機能を使いこなして安全かつ高速なWebアプリケーションを開発してください。
12月01日、Enterprise HTML5 Developers Meetup #2が21cafe@渋谷にて開催されました。多くの開発者の方にご参加いただき、盛り上がりました。
今回は全部で3つのセッションがありました。
Edison/Node.js/MQTT/BaaSによるIoTの始め方
MOONGIFT 中津川さん
私がSeleniumを使ってスクリーンショットを撮るまでに出会った闇の全て

新日鉄住金ソリューションズ 石川さん
Onsen UI 2.0とUIライブラリの未来

アシアル株式会社 久保田さん
また、LTでは飛び入りを含めてお二方がお話されました。


会場としてお借りした21Cafeの管理人の方もレポートを書いてくださっています。
次回は2016年の頭に行う予定です。ぜひご参加ください!
Seleniumを使ったテストの中で厄介なのが画面遷移を伴う操作で、画面の読み込み完了判定を行う時ではないでしょうか。StackOverflowでも同様の質問があがっており、その際に解答に上がっていたのは、
IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
のようにJavaScriptを実行してreadyStateを監視するというものでした。
Pitaliumでは専用のメソッドを提供しています。それがPtlWebDriverのuntilLoadです。使い方は以下の通りです。
driver.get(url);
PtlWebDriverWait wait = new PtlWebDriverWait(driver, 30);
// ロードするまで待つ
wait.untilLoad();
// ロードが完了してからスクリーンショットを取得する
assertionView.assertView("load_complete");
untilLoadの実際のコードは次のようになっています。
/**
* ページのLoadイベント終了まで待機します。
*/
public void untilLoad() {
final int sleepMillis = 100;
try {
Thread.sleep(sleepMillis);
String beforeURL = getURL();
try {
addElement(DUMMY_TAG_ID);
// このタイミングでページが切り替わるとタイムアウトを待つため、時間がかかる。
until(FIND_DUMMY_TAG_CONDITION);
deleteElement(DUMMY_TAG_ID);
} catch (Exception ex) {
String afterURL = getURL();
if (!beforeURL.equals(afterURL)) {
LOG.warn("wait前と後でページが切り替わっているため、waitを継続します");
// URLが違う場合、切り替わっていないため、もう一度実行する。
untilLoad();
} else {
throw new TestRuntimeException(ex);
}
}
} catch (InterruptedException e) {
throw new TestRuntimeException(e);
}
}
このようにダミーのDOMを追加して、その状態を見て読み込み状態を判別するようになっています。
簡単に使えますのでぜひ試してみてください。
今回はSelenium HubとNodeについてです。概ね想定できる設定について、主な設定箇所と注意するべきポイントをまとめてみました。どのような環境で構築したら良いのか、テスト環境構築方針を考慮する参考にして下さい。
HubとNodeが同一サーバで稼働している場合
この場合、明示的にHubとNodeを分けてサーバを起動させる必要はありません。

実行方法も、以下の通りコマンドラインから稼働させる事が出来ます。
java -jar selenium-server-standalone-2.48.2.jar
ただ、外部からのNode接続がある、もしくは今後その想定である場合はHubとNodeで分けた方が良いでしょう。
HubとNodeがリモートサーバ側にある場合
テスト環境からみて、Seleniumサーバが外部に存在する場合です。このケースではHubとNodeサーバを設定した方が良いでしょう。

Hubの起動
java -jar selenium-server-standalone-2.48.2.jar -role hub
Nodeの起動
java -jar selenium-server-standalone-2.48.2.jar \
-role node \
-nodeConfig NodeConfigBrowser.json \
-Dwebdriver.chrome.driver=chromedriver
ケース図でのnodeConfig設定 NodeConfigBrowser.json
{
"capabilities": [
{
"browserName": "firefox",
"maxInstances": 3,
"seleniumProtocol": "WebDriver"
},
{
"browserName": "chrome",
"maxInstances": 3,
"seleniumProtocol": "WebDriver"
},
{
"browserName": "safari",
"maxInstances": 3,
"seleniumProtocol": "WebDriver"
}
],
"configuration": {
"hub": "http://192.168.0.100:4444/grid/register"
}
}
テスト環境では、リモートに接続する設定が必要になります。
environmentConfig.json 環境設定をHubのアドレスに設定します。
{
"hubHost": "192.168.0.100",
"hubPort": 4444
}
capabilities.json プラットフォーム指定は対象のサーバに合わせて下さい。
[
{
"platform": "LINUX",
"browserName": "chrome"
}
]
HubとNodeがリモートサーバ側にあり、さらにNodeが別のサーバの場合
Hubが確定してしまえばNodeがどこに増えたとしても基本的には同じです。

Nodeサーバの設定では configuration 項目で hub のアドレスを正しく設定します。
ただしテスト環境の capabilities.json ファイルでは注意が必要です。上記の例だとMac環境がSafariになっていますので、platformは MAC とする必要があります。
[
{
"platform": "MAC",
"browserName": "safari"
},
{
"platform": "LINUX",
"browserName": "chrome"
},
{
"platform": "LINUX",
"browserName": "firefox"
}
]
このようにテストが行なえるノードを確認しておかないと、接続できなくなる(対象のNodeがない)と言うことになりかねません。
まとめ
簡単にサーバ設定をみていきましたが、いかがでしたでしょうか?本番環境と等しく、あらかじめテストのためのサーバ構成を考慮することは大事です。参考にしてください。
Pitaliumに関する過去の記事はこちら
前回までの記事で、すでにPitaliumを利用したデバッグ環境ができあがっていると思います。今回は、Jenkinsを利用して、PitaliumのCI(継続的インテグレーション)周りを見ていきましょう。尚、今回のサーバー構成とそのプロセスは次のような形を想定しています。

本テストではJenkins、Selenium Hub、Nodeサーバは全てDockerでの設定とします。管理されるコードはGitHubとし、JenkinsによりコードのチェックアウトとGradleを起動して、Seleniumサーバへ接続します。
今回はGitHubのリポジトリよりコードを取得しますので、あらかじめテストコードをGitHubへ配備しておきましょう。また、前回までの記事の中のSeleniumサーバとGradleの設定を利用しますので、ぜひ本シリーズの記事も合わせてご覧下さい。
1.Dockerを利用してJenkinsとSeleniumサーバを立ち上げる
まずは、Dockerを利用してJenkinsを立ち上げましょう。WindowsユーザもMacユーザもDocker Toolboxが利用できます。Docker Toolbox | dockerよりツールをダウンロードしてインストールして下さい。
※ 執筆時点ではWindowsでの動作は不安定のようです。MacもしくはLinux環境での利用をお勧めします。
今回はKitematicでDockerをコントロールしていきます。インストールして起動するとこのような画面が表示されます。

ここからJenkinsを選び、CreateボタンをクリックするとJenkinsのインストールが始まります。
インストールが完了するとJenkinsの起動画面となります。VOLUMESをクリックしてJenkinsが利用するディレクトリを設定します。

その後、左上あたりの「WEB PREVIEW」をクリックするとJenkinsが起動します。
次にSeleniumのサーバを設定、起動します。こちらはコマンドラインから以下のコマンドを実行して下さい。
docker run -d -p 4444:4444 --name selenium-hub selenium/hub
docker run -d -v /dev/urandom:/dev/random -P --link selenium-hub:hub selenium/node-chrome-debug
Dockerの設定は以上です。改めてDockerは便利だと感じます。
2.リソースファイルの修正
capabilitiesのplatform項目をLINUXとします。
/src/test/resources/capabilities.json
[
{
"platform": "LINUX",
"browserName": "chrome"
}
]
environmentConfig.jsonにSelenium hubのアドレスを指定します。
/src/test/resources/environmentConfig.json
{
"hubHost": "xxx.xxx.xxx.xxx",
"hubPort": 4444
}
Selenium Hubの起動アドレスの取得方法は色々ありますが、DockerのKitematicから下記の通り表示されますので、その値を設定して下さい。

3. Jenkinsでプロジェクトを設定する。
Jenkinsが起動すると次のような画面が表示されます。

今回はGitHubのリポジトリを利用しますので、GitHubプラグインのインストールが必要になります。まずはJenkinsのプラグイン設定を行います。サイドメニューよりJnekinsの管理 -> プラグインの管理 と進みます。

プラグイン管理の画面で 利用可能 タブをクリックして、左上のフィルタの項目に git plugin と入力します。絞り込まれた中に GIT plugin がありますのでチェックを入れて下さい。その後 再起動せずにインストール をクリックします。

すぐにインストールが始まります。念のため インストール完了後、ジョブが無ければJenkinsを再起動する にチェックを入れ、Jenkinsを再起動しておきましょう。

再起動したら、ダッシュボードから新しいジョブをクリックします。ジョブ名は pitalium-job としましたが任意でOKです。そして フリースタイル・プロジェクトのビルド にチェックして、 OK ボタンをクリックして下さい。

すぐにプロジェクトが作成され設定画面が開きます。プロジェクト名は入っていますが変更も可能です。

ソースコード管理のセクションで Git にチェックを入れます。リポジトリの設定フィールドが展開されますので、GITのデータを Repository URL、Credentials の項目に設定します。Credentials は新しく追加をしておきます。Credentialsの 追加 ボタンをクリックして、次の画面を表示します。

ユーザ名、パスワード にGitHubリポジトリにログインする値を設定して下さい。
下の方にスクロールして、ビルドセクションにテストのためのシェルの記述を行います。ビルド手順の追加 -> シェルの実行 をクリックすると、スクリプトの記入エリアが展開されます。ここに以下の一行を追記します。
$WORKSPACE/gradlew clean build

保存して終了します。そしてサイドメニューより ビルド実行 をクリックして下さい。問題がなければビルド履歴に正常終了を表す青丸となって終了します。正常終了の場合、Resultディレクトリ配下にスクリーンショットが配備されていますので確認して下さい。

赤丸となった場合は何らかのエラーですので、次の項目を再度チェックしてみて下さい。
- リポジトリは正しいか?(ID、パスワードを含む)
- コードはチェックアウトされているか?
- VOLUEMESのディレクトリをクリックしてチェックして下さい。
デフォルトでは/var/jenkins_home/jobs/pitalium-job/workspace/配下に配備されます。 - DockerのSeleniumサーバは起動しているか?(ポートなどもチェック)
最後に
Jenkinsを利用してPitaliumを利用することで、定期的にテストを実行することが可能になります。Jenkinsは便利な反面、導入までの敷居が高いですが、Dockerを利用する事で簡単に設定することができました。
Seleniumサーバの設置も思いの外、簡単だったと思います。これを機会にぜひ導入を検討してみて下さい。
Pitaliumに関する過去の記事はこちら
Pitaliumを使う際にはSelenium Gridを構築する必要があります。中央集約的にSelenium Hubというサーバを立てて、そこにぶら下がる形でSelenium Nodeを立てていきます。
Selenium Hubを立てても良いのですが、管理を簡易化するためにDockerを使った方法を紹介します。
Docker Toolboxを使おう
UbuntuやCentOSといったLinux環境であればDockerのインストールはさほど難しくありません。apt-getやyumを使ってインストールできます。対してWindowsやMac OSXの場合はLinuxの仮想環境を構築して、そこにDockerをインストールする必要があるので若干手間がかかります。そこで使いたいのがDocker Toolboxです。Docker Toolboxを使えばDockerに必要な環境が簡単にインストールできます。
インストールするとDockerはもちろんのこと、VirtualBoxであったり、Docker Machine、Docker Compose(Mac OSXのみ)などがインストールされます。インストール後、専用のコマンドプロンプト/コンソールを開くスクリプトが生成されますので、それを実行します。
Dockerを実行する
Dockerを起動したら、Selenium Hubのイメージを取得します。
$ docker run -d -p 4444:4444 --name selenium-hub selenium/hub:2.48.2
これだけでSelenium Hubが立ち上がります。Selenium Hubにアクセスする場合は、仮想環境のIPアドレスなので http://192.168.99.100:4444/grid/console などになるかと思います。
そしてさらにこの環境向けにGoogle ChromeやFirefoxを使いたい場合は、
$ docker run -d --link selenium-hub:hub selenium/node-chrome:2.48.2
$ docker run -d --link selenium-hub:hub selenium/node-firefox:2.48.2
でそれぞれ準備ができます。この二つを接続すると、Selenium Hubの管理画面は次のようになります。

Safariを接続する
今回はMac OSX上で実行していますので、Safariも接続してみます。まず最初に専用のSafari機能拡張が必要です。これはSeleniumのGitリポジトリでコンパイルするのが推奨されますが、Google Code上で公開されているものを使うこともできます。ただ2.45で更新が止まっていますので最新版のSafariでは動かない可能性がありますのでご注意ください。
次にApple Developer Program – Apple Developerとして登録し、証明書を作成する必要があります。この辺りの手順は省きますが、iOSアプリの開発時に作成する証明書の手順と同等になります。
機能拡張をインストールすると、次のように表示されます。

インストールが終わったらSeleniumを自分でコンパイルするか、バイナリ公開されている最新版である2.48.2をダウンロードして、次のようにコマンドを実行します。
java -jar selenium-server-standalone-2.48.2.jar -role node -browserName=safari -hub http://192.168.99.100:4444/grid/register
これでSafariが接続されました。接続されると次のように表示されます。

テストスクリプトを書いてみる
今回はテストスクリプトとしてRubyで書いてみました。予め gem install selenium-webdriver を実行しておきます。
require 'selenium-webdriver'
require 'rspec/expectations'
include RSpec::Matchers
def setup
@driver = Selenium::WebDriver.for(
:remote,
url: 'http://192.168.99.100:4444/wd/hub',
desired_capabilities: :safari) # you can also use :chrome, :safari, etc.
end
def teardown
@driver.quit
end
def run
setup
yield
teardown
end
run do
begin
@driver.get 'http://www.htmlhifive.com/'
# hifive - HTML5 Development Platform for Corporate Web Systems - hifive
expect(@driver.title).to eq('hifive - HTML5企業Webシステムのための開発プラットフォーム - hifive')
rescue
end
end
これはSafariを起動するスクリプトなので、Mac OSXのSafariが立ち上がってhifiveのサイトが表示されます。

safariとなっているところをchrome、firefoxに変更すると、それぞれDocker内部で立ち上がって実行されます。そのため、この場合はブラウザが立ち上がることなくテストができますので邪魔になりません。もし実行している状態を見たい場合は、Selenium Nodeを
$ docker run -d -P --link selenium-hub:hub selenium/node-chrome-debug:2.48.2
$ docker run -d -P --link selenium-hub:hub selenium/node-firefox-debug:2.48.2
として立ち上げ、その上で
$ docker ps
CONTAINER ID IMAGE
4211324efc16 selenium/node-firefox:2.48.2
356db01e6bd2 selenium/node-chrome:2.48.2
f016e29aa44a selenium/hub:2.48.2
を実行してコンテナIDを確認し、
$ docker port 4211324efc16 5900
と実行することでVNCサーバのポートが開きます。後はRealVNCやMac OSX標準の画面共有アプリなどを使って接続できます。
Dockerを使えばテスト環境の構築がとても手軽になります。Selenium Hubを立ち上げれば、後はWindowsやMac OSXなどは関係なく、それぞれHubにつないでテストできるようになります。テストマシンを用意することで個々のマシンの負荷も軽減でき、さらにテストの自動化も考えられるようになるでしょう。
Pitaliumに関する過去の記事はこちら
Pitaliumはスクリーンショットを利用して画面の差分比較ができるのがPitaliumの最大の特徴です。そのためにはまず基準となるスクリーンショットが必要になり、それをテスト実行モードで切り替えることで実現しています。今回は実際に差分比較を行うためのワークフローを見ていきましょう。
なお、利用しているのはTODO管理になります。
実行モードについて
画面比較を行うにあたって基準となる画面をキャプチャするのですが、Pitaliumには幾つかの実行モードがあります。それぞれ次のようになっています。
| モード | 内容 |
|---|---|
| TAKE_SCREENSHOT | スクリーンショットの取得のみ(Assertionは無視) |
| SET_EXPECTED | 比較基準値となる画面を作成するモード(デフォルト) |
| RUN_TEST | 基準画面との比較を行うモード |
このモードは以下のファイルに記載するか、JUnitの実行時パラメータに含めることで変更できます。
src/main/resources/environmentConfig.json
{
"execMode": "RUN_TEST"
}
JUnit VM実行パラメータに含める場合
-Dcom.htmlhifive.pitalium.execMode=RUN_TEST
モードの詳しい仕様はライブラリ仕様 – hifiveでも確認できます。
現在の状態を保存してみる
それではテストを行うための比較基準となる画面を取得してみましょう。先に説明したとおり、モードをSET_EXPECTEDとして実行するだけです。
なお、デフォルトで指定がない限りモードはSET_EXPECTEDとなります。この場合、当然ですが画面比較は行われませんので注意して下さい。
public class PitaliumTodoTest extends PtlTestBase {
@Test
public void test1() throws Exception {
// TODOサイトのトップページを開きます
driver.get("http://www.htmlhifive.com/ja/tutorial/todo/");
// 比較対象を使用して検証を実行します。
assertionView.assertView("ToDoTOP");
}
}
上記をテスト実行すると、デフォルト設定では次のディレクトリに各画像や基準値のデータが設定されます。
実行日付のディレクトリ以下、テストクラス名とその画像が保存されます。以下は、そのディレクトリ例です。
results
├── 2015_11_10_13_43_41
│ └── PitaliumTodoTest
│ ├── result.json
│ ├── test1_ToDoTOP_MAC_chrome.json
│ ├── test1_ToDoTOP_MAC_chrome.png
│ └── test1_ToDoTOP_MAC_chrome_TAG_NAME_body_[0].png
└── currentExpectedIds.json
この中で、currentExpectedIds.jsonに、基準値となる情報が入ります。
{
"PitaliumTodoTest" : {
"test1" : "2015_11_10_13_43_41"
}
}
上記の場合テストケースのtest1は、result/2015_11_10_13_43_41にある基準画像を利用するという意味になります。
比較してみよう
それでは、実際に比較してみましょう。テストケースから画面TODO項目を追加する処理を入れて比較してみます。実行モードは、RUN_TESTとして下さい。
public class PitaliumTodoTest extends PtlTestBase {
@Test
public void test1() throws Exception {
// TODOサイトのトップページを開きます
driver.get("http://www.htmlhifive.com/ja/tutorial/todo/");
// 新しくTODO内容を追加します。
driver.findElementById("txtTodo").sendKeys("新しくTODO追加");
driver.findElementById("btnRegist").click();
// 比較対象を使用して検証を実行します。
assertionView.assertView("ToDoTOP");
}
}
上記でJUnitを実行すると、項目が新しく追加されて基準値となる画面と比較して変更が出ていますのでテストはエラーとなります。

※ 画面はIntelliJ IDEAのものです。
以上が、Pitaliumの画面比較機能の利用方法です。
部分的なDOMに変更があった場合
Pitaliumはもう一つ画面比較の特徴があり、DOMレベルで画面比較が可能です。Pitalium 1.0.1で加えられたBuilderパターンを使用し、addNewTargetメソッドでDOM要素を設定します。DOM要素は複数指定可能です。
@Test
public void test2() throws Exception {
// TODOサイトのトップページを開きます
driver.get("http://www.htmlhifive.com/ja/tutorial/todo/");
// 比較対象をDOMレベルで指定します。
ScreenshotArgument arg = ScreenshotArgument.builder("ToDo-LastChild")
// 撮影対象を指定
.addNewTarget(SelectorType.ID, "list")
.addNewTarget(SelectorType.CSS_SELECTOR, "#list tbody tr:last-child")
.build();
// 比較対象を使用して検証を実行します。
assertionView.assertView(arg);
}
また、部分的に比較を行わないという操作なども可能です。次のように、addExcludeメソッドで指定します。
@Test
public void test3() throws Exception {
// TODOサイトのトップページを開きます
driver.get("http://www.htmlhifive.com/ja/tutorial/todo/");
ScreenshotArgument arg = ScreenshotArgument.builder("ToDo-LastChild")
// 比較対象をDOMレベルで指定します。
.addNewTarget(SelectorType.ID, "list")
// DOMレベルで除外指定します。ここでは、最後のTODO項目を除外します。
.addExclude(SelectorType.CSS_SELECTOR, "#list tbody tr:last-child")
.build();
// 比較対象を使用して検証を実行します。
assertionView.assertView(arg);
}
テストケース・エラー時のワークフロー
実際のプロジェクトが進めば、当然エラーになるケースが出てくるでしょう。この場合、まずはエラーとなったケースを見極めることから始めます。大きく分けて次の2通りとなるでしょう。
テストケースが問題の場合
- 画面のレイアウト変更があった
- 文言の修正が入った
- 動的なコードが挿入された
テストケースが問題の場合は、もう一度基準画面を取り直すことでOKでしょう。ただし動的なコードが挿入された場合は比較から除外するなどのテストコード修正が必要になります。
コードが問題の場合
- 間違えてCSSを弄った
- 間違えてレイアウトを変更してしまった
こちらはテストケースに影響がないので対象のクラスや画面テンプレートを正しく変更し、再度テストを行えば良いでしょう。
また、Pitaliumの画面比較チェックは当然ですが内部的なコードの解析は行われません。その辺りは、Selenium側のテストで行えばよいでしょう。
最後に
Pitaliumを利用した画面比較のワークフローを見ていきましたが、いかがでしたでしょうか。簡単に設定が可能ですし、ワークフローさえ手順化されていればテストで迷うことはないと思います。
ただしPitaliumの画面比較を導入する場合は、その導入時期を見極める必要があるでしょう。頻繁に画面が更新される初期の開発において画面比較チェックまで含めてしまうとテストケースで頻繁にエラーが起こり、その都度テストが止まってしまう可能性が大きいです。導入は時期を見て、画面レイアウトが固まった段階で行うべきでしょう。
Pitaliumにご興味のある方はチュートリアル(Pitalium:hifiveリグレッションテストライブラリ) – hifiveも参考にして下さい。
過去のPitaliumの投稿はこちら