Robot+JUnitによる、Webアプリケーションの自動テスト

少々詳しい解説と機能拡張

どういう仕組みかというと

「どうやってテスト対象のコンテンツに、テストツールからアクセスするか」これが最大の難問です。

セキュリティの関係上、異なるオリジン(ドメイン)からロードされたコンテンツ同士が、互いにアクセスする方法はありません(できたら大問題です)。

そこで、当ツールでは、テスト対象のコンテンツを、強制的にテストツール(テスト用のマネージャコンテンツ)と同じオリジンからロードさせるために、HTTPのゲートウェイサーバを利用します。

動作イメージの概略は、以下のとおりです。

動作概略のシーケンス

これにより、マネージャコンテンツとテスト対象のアプリケーションが同じオリジンとなるので、マネージャコンテンツは、アプリケーションのコンテンツに、自由にアクセスできるようになります。

初期処理

JUnitを実行すると、最初にゲートウェイサーバを起動し、Webブラウザからの接続を待ちます。

Webブラウザでゲートウェイサーバにアクセスすると、マネージャコンテンツがゲートウェイサーバからロードされます。

マネージャコンテンツは、JUnit上のゲートウェイサーバにWebSocketで接続し、自身のロードが終了したことを通知します。

初期処理のシーケンス

初期処理

テスト対象コンテンツのロード

JUnitで、テスト対象コンテンツのロードを指示すると、ゲートウェイサーバのWebSocketを経由して、Webブラウザ上のマネージャコンテンツに指示が通知されます。

マネージャコンテンツは、Windowをオープン後、ゲートウェイサーバにテスト対象のアプリケーションをロードするリクエストを発行し、返却されたコンテンツをオープンしたWindowに表示します。

マネージャコンテンツは、アプリケーションのロードが終了した時点で、オープンしたWindowの位置やサイズなどの情報を含めて、WebSocketでゲートウェイサーバに、ロードの終了を通知します。

テスト対象コンテンツロードのシーケンス

テスト対象コンテンツのロード

マウスの操作と画面遷移

マウスで特定の要素をクリックするためには、その要素のスクリーン上の位置を取得する必要があります。

JUnitで、要素位置取得を指示すると、ゲートウェイサーバのWebSocketを経由して、Webブラウザ上のマネージャコンテンツに指示が通知されます。

マネージャコンテンツは、Windowに表示しているテスト対象のアプリケーションコンテンツから、指定された要素の位置を取得して、ゲートウェイサーバに返却します。

JUnitは、返却された情報を元に、マウスを移動しクリックします。

JUnitで、ページ遷移の監視を指示すると、ゲートウェイサーバのWebSocketを経由して、Webブラウザ上のマネージャコンテンツに指示が通知されます。

マネージャコンテンツは、新しいページがロードされたことを検知すると、表示中のページの情報をゲートウェイサーバに返却します。

マウス操作と画面遷移のシーケンス

マウス操作と画面遷移

JUnitソース

上記シーケンスのテストを実施するためのJunitソースは以下のとおりです。「まずは、簡単なご紹介」の最初に照会したサンプルと同じものです。

次頁に遷移するJUnit

4行目のsetUpBeforeClassメソッドの処理が、「3-1-1. 初期処理」となります。

19行目のOperation.openWindowが、「3-1-2. テスト対象コンテンツのロード」です。

22行目のOperation.clickElementが、「3-1-3. マウスの操作と画面遷移」のマウスクリックまでです。

23行目のOperation.onloadWaitが、「3-1-3. マウスの操作と画面遷移」のページ遷移監視です。

マネージャコンテンツへの通知の詳細

只今準備集です。

いくつかの問題とその解決策

フルパスの問題

A要素のhref属性や、FORM要素のaction属性にフルパスが設定されている場合、ゲートウェイサーバ経由でのリクエストができないので、当ツールは正しく動作しません。

このようなケースでは、属性に設定されている内容を書き換えることでテストを行うことができます。

但し、属性を書き換えてもテストが有効かどうかは、判断してください(遷移先が正しいかというテストで、属性の遷移先を書き換えてテストをしても、テストの意味がありません)。

フルパスが記述されたHTML
属性の書き換え

7行目で、idがnextpageの要素のhref属性を、nextpage.htmlに書き換えます。

他のホストのコンテンツをロードするような場合は、URLを以下のようにします。

http://localhost:8080/__gateway__/http://otherhost/other.html

http://localhost:8080/__gateway__/の後ろが、ロードするコンテンツのURLとなります。

ホスト名とポートは、実行しているゲートウェイサーバの環境に合わせてください。

オープンしたWindowの問題

アプリケーションがオープンしたWindowを操作する場合、そのWindowに名前があれば、下記コードで実現できます。

windowInfo = Operation.openWindow(null, "__NEW_WIN__", "");

__NEW_WIN__が、オープンされたWindowの名前(window.openメソッドの第2引数に渡した値)です。

しかし、Windowに名前が無い場合、アクセスできないので操作もできません。

リダイレクトの問題

リダイレクト先のロケーションに、相対パスを返すサーバには対応していません。

テスト対象のアプリケーションは、リダイレクト先のロケーションに、絶対パスを返すことを確認してください。

これは、ゲートウェイサーバの問題なので、将来的には対応する予定です。