Webアプリケーションのクライアント側のテストといえば、JsUnit等が使われていますが、イベントに関するテストはなかなか自動化が難しいものです。特に、様々な環境でテストを行う必要があるWebアプリケーションでは、環境毎にツールを用意しなければならないとすると、かなりの負担になります。
しかし、うれしいことに、JavaにはRobotという、GUIのテストを行うためのクラスが用意されており、このクラスはネイティブのイベントを発行することが出きるのです。要するに、Javaを実行できる環境であれば、Webブラウザ上のアプリケーションに対し、マウスやキーボードのイベントを発生させて自動実行することが出来るということです。
XMLで定義したテストケースを実行することができます。テストケースには、JavaScriptのコードを指定できますが、自動テスト用の機能として「指定の要素上にマウスを移動させる」「マウスの指定のボタンをクリックする」「キーボードの指定のキーを押下する」「画面の指定箇所をキャプチャし、画像として保存する」「コンテンツの読み込みが終了するのを待ち合わせる」なども用意されています。
簡単なサンプルをいつくか紹介します。
1: <doc> 2: <exec><![CDATA[loadContent('index1.html')]]></exec> 3: <exec><![CDATA[jsRobot.mouseMoveToId('ah01')]]></exec> 4: <exec><![CDATA[jsRobot.mouseLeftClick()]]></exec> 5: <exec><![CDATA[contentLoadWait()]]></exec> 6: <exec><![CDATA[newWindow.alert('完了しました。')]]></exec> 7: </doc>
上記の例では、windowをオープンし、そこに index1.html をロードします(2行目)。
ロード完了後、idが'ah01'の要素の上にマウスポインタを移動し、左ボタンをクリックします(3行目4行目)。
マウスクリックにより画面が遷移するので、その完了を待ちます(5行目)。
「完了しました。」という文言をダイアログで表示します(6行目)。
1: <doc> 2: <exec><![CDATA[loadContent('index5.html')]]></exec> 3: <exec><![CDATA[jsRobot.mouseMoveToId('in_01')]]></exec> 4: <exec><![CDATA[jsRobot.mouseLeftClick()]]></exec> 5: <exec><![CDATA[jsRobot.keyType(243, false,false,false,false)]]></exec> 6: <exec><![CDATA[jsRobot.keyType(65, false,false,false,false)]]></exec> 7: <exec><![CDATA[jsRobot.keyType(73, false,false,false,false)]]></exec> 8: <exec><![CDATA[jsRobot.keyType(85, false,false,false,false)]]></exec> 9: <exec><![CDATA[jsRobot.keyType(10, false,false,false,false)]]></exec> 10: <exec><![CDATA[jsRobot.keyType(243, false,false,false,false)]]></exec> 11: </doc>
上記の例では、windowをオープンし、そこに index5.html をロードします(2行目)。
ロード完了後、idが'ah01'の要素の上にマウスポインタを移動し、左ボタンをクリックします(3行目4行目)。
IMEを起動します(Windowsのみ)(5行目)。
"あいう"と入力します(6行目7行目8行目)。英数字の入力であれば、jsRobot.inputText('Abcd1234')
という記述も出来ます。
Enterキーで確定します9行目)。
IMEを終了します(Windowsのみ)(10行目)。
1: <exec><![CDATA[jsRobot.mouseMoveToId('div09')]]></exec> 2: <exec><![CDATA[jsRobot.mouseLeftPress()]]></exec> 3: <exec><![CDATA[jsRobot.mouseMoveFromHere(160, 120)]]></exec> 4: <exec><![CDATA[jsRobot.mouseLeftRelease()]]></exec>
ロード完了後、idが'div09'の要素の上にマウスポインタを移動し、左ボタンを押し下げます(1行目2行目)。
マウスポインタを、x方向に160ピクセルy方向に120ピクセル移動します(3行目)。
左ボタンを離します(4行目)。
他にも、画面のイメージキャプチャや、各処理の実行間隔の変更、特定の処理を指定回数繰り返すことなども出来ます。
操作した通りの処理を繰り返すテストケースを、作成します。
もう少し詳細な解説は、しばらくお待ちください。
テストのエビデンスとして、画面のイメージが必要な場合も多いと思いますが、結構面倒なものです。
この機能は、画面遷移を検知した場合、遷移直前(前の画面)と遷移直後(後の画面)の画面イメージを自動的にキャプチャして、ファイルに保存するものです。
ファイル名は、日付時刻と画面のtitle及び、ロード時アンロード時の区分となります。ファイルは、PNG形式となります。
もちろん(というか残念ながら)、こういう便利な代物には、但し書きが付き物です。
マウスイベントを発生させてボタンを押そうとしても、そのボタンがどこにあるかが分からなければいけません。マウスカーソルをボタンの上に移動させて、左ボタンを押して放すというイベントを発生させることになりますが、カーソルの移動時に指定するポジションは、当然スクリーン上のポジションとなるため、Webブラウザ上のボタンが、スクリーン上でどのポジションにあるかを、何らかの方法で算出する必要があります。
解決策として、当コンテンツではJava Appletを使用しています。Java Appletはjavascriptからアクセスできるため、Webブラウザ上の要素の位置をjavascriptにより特定し、その位置をJavaのメソッドに渡すことが出来るのです。
しかし、キーボードやマウスのイベントを自由に発生させることが出来るということは、デスクトップを自由に操作出来るということに他なりません。もし、Java Appletで自由にRobotが使えるとすると、これは危険極まりないセキュリティホールです。
そこで、Javaの開発者は、特別な許可が無い限り、Robotクラスのインスタンスを作成できない様に設計しました。そして、標準では、Java Appletにこの許可はありません。
テストを実行するには、お使いのjvmにセキュリティポリシを追加する必要があります。そのため、当サイトで動作するサンプルページを公開するということが出来ません(当サイトからロードしたクラスに、Robotクラスのインスタンス作成権限を与える必要があるためです。そこまで私を信じてくれというほど図々しくは...)。
ということで、動作に必要なファイルをまとめたアーカイブを用意しました。ダウンロードして、ローカルで実行してみてください。動作に必要な前提環境は以下のとおりです。
Webブラウザ | OS | バージョン | 備考 |
---|---|---|---|
Firefox | Linux | 10 | 3.5は動作しません。 自動実行の対象を新しいウィンドウで開くようにしてください。タブで開いた場合、タイマの間隔が最低1000ミリ秒となってしまうので、非常に動作が遅くなります。「オープンしたWindowのタイマを使用する。」をチェックするとそれなりに動作しますが、自動実行の対象がダイアログを表示した場合、タイマが停止するので、それ以降の処理が実行されません。 |
Firefox | Window XP | 3.6, 5, 10 | Linux版と同じ。 |
Chrome | Linux | 17 | タイマに関しては、Firefoxと同様の問題があります。「オープンするWindowの設定」でスクロールバーにチェックを付けると、Tabを開いてしまいます。Windowを開く場合は、スクロールバーのチェックを外してください。 但し、一つのウィンドウ/タブでダイアログが表示されると、他のウィンドウ/タブの処理もブロックされる(タイマが動作しない)ので、ダイアログのOKボタンを押下するといった処理は実行せきません。 |
Chrome | Windows XP | 17 | Linux版と同じ。 |
IE | Windows XP | 6, 7, 8 | 8以上では、TABの動作を変更する必要があります。 ダイアログが表示されると、マウスカーソルがウィンドウの外に出たと通知されるので、デフォルトでは自動実行が中断されます。その場合は、「...自動実行を中断する。」のチェックを外してください。 |
IE | Windows 7 | 8, 9 | 同上 |
Safari | Windows XP | 5 | 動作はしますが、Javaの例外が頻発し、使い物になりません(TT) ダイアログに関して、Chromeと同様の問題もあります。 |
Opera | Windows XP, 7 | ウィンドウ/タブの表示方法よっては正しく動作しません。設定画面の詳細設定-タブ-追加のタブオプションで、常に最大化して表示を選択してください。 |
環境 | 詳細 | 備考 |
---|---|---|
Java実行環境 | java5以上で動作しますが、Java7を奨励します | セキュリティポリシの変更を行う必要があります。また、セキュリティ上の問題もあるので、できるだけ最新のバージョンを使用するようにしてください。 |
Webサーバ | 確認済みのサーバは、Apache2.2 | 必ずローカルマシンかローカルネットワーク内に、Webサーバを用意してテストしてください。 |
キーボード | キー配列が106か109 | Windowsでは、殆どのASCIIコードが扱えますが、'_'(アンダースコア)のみ、入力できません。また、':'と';'のキーでイベントキャプチャが正しく動作しません。 Linuxの場合も入力はWindows同様ですが、英数字以外のイベントキャプチャは、殆ど使い物になりません。 |
お使いの環境でJava Appletを動作させるためには、JavaのインストールとWebブラウザの設定が必要です(設定の不要な場合も有ります)。
下記URLからzipファイルをダウンロードしてください。
ダウンロード 2012/11/18 Update
ダウンロードしたzipファイルを解凍してください。以下のようなディレクトリ構成となります(以前のバージョンとは、ディレクトリ構成・ファイル構成共に変更となっています)。
yscjp_apps/ +- jslib/ | +- nn.nn.nn.nn/ +- webtest/ +- com/ | +- yscjp/ | +- webtools/ | +- robot/ +- webtest.html
nn.nn.nn.nnは、バージョン番号です。1つのアーカイブに複数のバージョンが含まれる場合があります。
上記は、ファイルの一部を記載しています。実際のディレクトリ内には、他にもファイルが存在します。
yscjp_appsディレクトリを、Webサーバがアクセスできる位置にコピーしてください。以降の説明は、ユーザディレクトリの直下にコピーした場合を想定しています。
public_html/ +- cgi-bin/ +- yscjp_apps/
http://localhost/~[ユーザID]/yscjp_apps/webtest/webtest.html
にアクセスすると、テスト画面が表示されしばらくしてJavaのコンソールが表示されます(コンソールを開く指定となっている場合)。Javaのコンソールが表示されない場合、Webブラウザの設定を見直してください。
Javaのセキュリティポリシーを設定していない場合、コンソールに例外が表示されます。
<<<<重要な警告>>>>
Javaのセキュリティポリシーの設定変更は、一つ間違えるとローカルマシンに、巨大なセキュリティホールを開けることになります。このコンテンツの指定通りに設定しても動作しないような場合に、適当に設定して動作させるというようなことは、絶対にしないでください。
ポリシーの設定は、ユーザ個別で設定する場合、以下のファイルに行います。
Linuxの場合
[ユーザHome]/.java.policy
Windowsの場合
c:/Documents and Settings/[ユーザID]/.java.policy
基本機能とイメージキャプチャで、設定する必要が有るセキュリティポリシーが異なります。
ポリシー | 内容 | 備考 |
---|---|---|
java.awt.AWTPermission | "createRobot"; | ロボットのインスタンス作成を許可します。 |
ポリシー | 内容 | 備考 |
---|---|---|
java.awt.AWTPermission | "readDisplayPixels"; | 画面のイメージキャプチャを許可します。 |
java.util.PropertyPermission | "user.home", "read"; | ユーザのホームディレクトリを、システムプロパティから取得することを許可します。 |
java.io.FilePermission | "${user.home}${/}-", "read, write, delete"; | ユーザのホームディレクトリのファイルに対して、読み込み・書き込み・削除を許可します。 画面のイメージを、ファイルに出力するためのものです。 |
ポリシーの設定は、classファイルをロードするURLに対して行います。上記の例では下記URLに対して設定することになります。
http://localhost/~[ユーザID]/yscjp_apps/webtest/-
リモートホスト上にテスト対象が存在する場合は、localhostの箇所をホスト名に変更しますが、可能な限りIPアドレスを指定するようにしてください。
grant codeBase "http://localhost/~[ユーザID]/yscjp_apps/webtest/-" { permission java.awt.AWTPermission "readDisplayPixels"; permission java.awt.AWTPermission "createRobot"; permission java.util.PropertyPermission "user.home", "read"; permission java.io.FilePermission "${user.home}${/}-", "read, write, delete"; };
<<<<重要な警告>>>>
このプログラムは、マウスやキーボードを操作します。何らかの原因で意図しない動作をした場合、ご利用のコンピュータに重大な影響を与える可能性が有ります。
ファイラ(エクスプローラ等)やその他マウスやキーボードの操作で重大な問題を引き起こす可能性のあるプログラムは、必ず終了した状態で実行してください。
作者は、このプログラムが引き起こした問題について、責任をとることが出来ませんので、自己責任の元実行してください。
デフォルトでは、オープンしたWindowの外にマウスカーソルが出た場合、テストを中断する設定となっていますが、タイミングなどにより、確実な中断を保証できません。
サンプルを実行する、簡単な操作方法です。詳細な操作方法に関しては、今後拡充していきます。
サンプルは、WebブラウザのWindowサイズが1000x800ピクセル程度あることを前提としています。Windowサイズが小さい場合、正しく動作しない可能性が有りますので、注意してください。新しくWindowをオープンする場合(Tabブラウザでは無い場合)、「テストケース実行時の設定」の高さや幅を指定してください。
Webブラウザで、http://localhost/~[ユーザID]/yscjp_apps/webtest/webtest.html
にアクセスします。
「テストケースの実行」タブを選択してください(この画面が初期表示画面です)。
テストケースで、test001.xmlを選択し、実行ボタンをクリックします。マウス操作により、リンクをたどってページ遷移をするサンプルです。マウスがリンク上に移動してクリックし、次画面のロードを待ちます。
同様に、test006.xmlを実行すると、キーボードからテキストを入力させることが出来ます。また、このサンプルは、最後に表示した画面のキャプチャイメージを[HOME]/capture/
に出力します。
単純にリンクをたどるサンプルです。同じ処理を3回繰り返し終了します。
フォームを操作するサンプルです。
環境によっては、正常に動作しない場合も有ります。
要素の各位置にマウスを移動するサンプルです。IE6では、正しく表示できません。
マウスドラッグで、要素を移動させるサンプルです。IE6では、正しく表示できません。
マウスドラッグで、要素のサイズを変更したり移動させるサンプルです。IE6では、正しく表示できません。
他のシナリオを読み込んで実行します。実行する処理の一部を書き換えることも出来ます。
条件分岐のサンプルです。終了処理と指定IDジャンプも含んでいます。
イベントキャプチャタブを選択します。
コンテンツURLに"index1.html"と入力し、読み込みボタンをクリックしてください。Window(または新しいタブ)がオープンし、index1.htmlがロードされます。"リンク先が存在する"をクリックし、ページが遷移した時点で再び"リンク先が存在する"をクリックしてください。
オープンしたWindow(または新しいタブ)を閉じます。
イベントキャプチャ画面で、キャプチャの終了をクリックすると、下のテキストエリアに、xmlが表示されます。
キャプチャ結果の実行をクリックします。キャプチャしたイベントが再現できれば成功です。
現時点のバージョンでは、キャプチャしたとおりにイベントが再現できるのは、単純なマウスクリックとキーボードからの英数字の入力だけです(矢印キーやEnterキーは、操作できます)。マウスのドラッグやキーボードからの記号入力は、Windowsでは問題有りませんが、殆ど思ったとおりになりません。漢字の入力(IMEの操作)もできません。
また、キャプチャの結果にjsRobot.mouseXXXXPress()
やjsRobot.mouseXXXXRelease()
がある場合は注意してください。
jsRobot.mouseXXXXPress()
のあと何らかの理由によりjsRobot.mouseXXXXRelease()
が実行出来なかった場合、デスクトップ上でマウスの操作が出来なくなる危険性が有ります。この様な事象が起きたときには、30秒程度で操作できるようになるはずですが、30秒を過ぎても操作が回復しない場合、キーボードを使って「Robotでテスト」の画面を表示し、“マウスボタンリリース”ボタンを押下してください(Tabキーでフォーカスを当ててEnterなど)。
キーボードでも同様の事象が発生することが有りますが、この場合はキーボードのキーを押すことで、通常は正常に戻ります。
コンテンツURLに"index1.html"と入力し、読み込みボタンをクリックしてください。Window(または新しいタブ)がオープンし、index1.htmlがロードされます。"リンク先が存在する"をクリックし、ページが遷移した時点で再び"リンク先が存在する"をクリックしてください。
ホームディレクトリにcapture
ディレクトリが作成されていて、その中にキャプチャ結果のイメージファイルが出力されていれば、成功です。
イメージキャプチャに多少の時間がかかるので、画面の遷移が終了しても次の操作まで、数秒以上待つようにしてください。