BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ アーティクル SeleniumでAjaxアプリケーションをテストする

SeleniumでAjaxアプリケーションをテストする

ブックマーク

Seleniumを一瞥

Q: 一般的なオンラインストアでは、買い物を完了するために多くのプロセスでユーザからの入力を必要とします。ソフトウェア開発者は自分の実装の品質と正しさをどうやって確認すればよいでしょうか?

それは、生活のためにWEBアプリケーションを開発している人たちがよくぶつかる疑問です。アプリケーションの機能をテストすることができれば本当に便利です。でもどうやってそれを実現すればよいでしょう?

Selenium(source)はThoughtWorksによって書かれたWEBアプリケーション専門のテスティングツールです。Seleniumのテストは実際のユーザがやるのと同じように直接ブラウザ上で実行されます。SeleniumはWindows、Linux、Mac上のInternet Explorer、Mozilla、Firefoxで動作します。

実際に動作しているSeleniumをオンラインデモ(source)で確認してみてください。右上の角にある「All」ボタンをクリックしてテストケースを実行します。うまくいけば、テストにパスしてきれいな緑色のバーが表示されるはずです。actionはassertよりも淡い緑色で表示されることに注目してください。これは何故かというと、actionはverifyコマンドやassertコマンドのように実際に何かをテストしているわけではないからです。 assertが失敗すると、失敗したコマンドは赤くなり、Seleniumは処理を中止します。一方verifyコマンドが失敗すると、やはり赤くなりますがテストは中止されません。


SeleniumのテストケースとテストスイートはHTMLで記述します。実際それらはただのHTMLの<table>要素に過ぎません。テストスイートの各行は次に示すようにテストケースへの参照です。

<tr><td><a href="MyTest.html">MyTest</a></td></tr>

テストケースは「Selenese」と呼ばれる形式で書かれたHTMLドキュメントとして表現され、そこにはコマンドと二つの引数のための十分なスペースをもった3カラムのテーブルがあります。典型的なテストケースは次のようになります。

「All」ボタンを押すなどしてテストを開始すると、SeleniumのテストランナーがHTMLのテストケースドキュメントを解釈し、一番下のフレームに表示されるWEBアプリケーションを動かします。

ユーザのアクションをシミュレートすることで、Seleniumはユーザインターフェースを通じたアプリケーションのテストを可能にします。もちろん単体テストの代わりにはなりませんが、私たちはWEBアプリケーションの受け入れテストを自動化するためによく使用します。定期的な再帰テストを自動化するために継続的インテグレーションにおけるビルドに組み込むこともできます。もっと深くSeleniumを知りたければ、オンラインドキュメント「Selenium: Usage」を参照(サイト・英語)してください。

Ajax

SeleniumはWEBアプリケーションの機能のいくつかがJavaScriptを使ってブラウザ上で実装されているときに特に便利です。

Ajax(Asynchronous JavaScript and XMLの略)は、インタラクティブなWEBアプリケーションを制作するための開発テクニックです。ページの背後にあるサーバと小さなデータをやりとりすることでユーザが変更を行うたびにWEBページ全体をリロードする必要をなくし、WEBページの反応をより良く感じさせることを意図しています。これは WEBページの双方向性や速度、ユーザビリティが高まることを意味します。

「Loading」というメッセージはAjaxで表示されている

Ajaxの技術的な定義はそういうことですが、大部分の人にとってのAjaxとはGMailやFlickrのように動作するWEBページのことです。リンクをクリックしてもページのリロードが起こらず、代わりにブラウザはサーバと通信を行い、表示中のページの一部だけを更新します。この、リンクをクリックしてから結果を確認するまでの待ち時間がことをややこしくするのです。

テキストフィールドとボタンを一つずつもっているWEBページがあるとしましょう。テキストフィールドの初期値は「oldValue」です。ボタンをクリックするとAjaxの魔法が発動して、テキストフィールドの値はページがリロードされることなく「newValue」に変わります。私たちはどうやってこれをテストすればいいでしょう? 明らかなアプローチは、ページを開いてボタンをクリックし、テキストフィールドの値を確認することです。でも Seleniumを使ってそれを行うと、テストケースは失敗してしまうのです。

テストが失敗する理由は恐らくそんなに明白ではありません。Ajax呼び出しは非同期な性質をもっており、結果はサーバからすぐに返ってくるわけではありません。だからフィールドの値はボタンをクリックした数秒後に変更されたのですが、Seleniumはすぐに値をチェックして古い値を見てしまったのです。では、Seleniumが結果を待つことを知らないのなら、私たちが素晴らしいAjaxの効果をテストされた状態で手に入れるにはどうすればよいのでしょうか?

待つ……

どうやってSeleniumに結果を待たせればよいでしょう? この問題を解決する方法の一つはclickの代わりにclickAndWaitコマンドを使うことです。この「AndWait」というサフィックスは、Seleniumがページのリロードを待つ必要があることを示しています。これはうまく動作するように思えるかもしれませんが、ここには落とし穴があります。ページはリロードされないので、clickAndWaitはSeleniumを永遠に待たせ続けることになります。これでは駄目なのは明らかです。

もう一つの可能性はclickassertValueの間に小休止をはさむことです。サーバが応答するのに十分な時間を与えるため、間で5秒間止めてみましょう。このアプローチなら大抵の場合はうまく動作しますが、サーバが応答に5秒以上かけると失敗してしまいます。これは様々な理由によって起こり得ます。ネットワークの遅延やテストマシンの過負荷など。結果を確認する前の一時停止期間をどんどん延ばしていってもよいですが、そうするとテストの実行もどんどん遅くなります。だからこれもベストな解決策ではありません。ちゃんと動くことが保証されませんし、テストは必要以上に遅くなってしまいますから。

ありがたいことに、Seleniumはまさに私たちが求めていることを行うためのサポートを提供してくれています。表示中のページでフィールド値が変更される場合、waitForValueコマンドを使えば、期待している値が表示されるまでSeleniumを待たせることができます。

なので、失敗しているテストを成功させるため、失敗するassertValueコマンドを次のように置き換えなければなりません。

このコマンドを実行すると、Seleniumは現在のテストケースの実行を一時停止し、期待している値を待ちます。「newValue」という文字列がテキストフィールドに表示されると、停止していたテストが再開します。もし期待している値のスペルを間違うと、 Seleniumは30秒間待ってタイムアウトするので、覚えておいてください。

あなたが多分すでに予想しているとおり、Ajaxの作用をテストするために利用できるコマンドはたくさんあります。例えば、Ajaxで更新されたプレーンテキストをチェックしたいならwaitForText、現在ページのタイトルをチェックしたいならwaitForTitle、HTML要素が削除されたことを検証したいならwaitForElementNotPresentなど。実は、Selenium Accessor(サイト・英語)それぞれに対して対応するwaitForXxxxコマンドとwaitForNotXxxxコマンドがあります。何かをチェックためのverifyXxxxassertXxxxがあるなら、非同期効果をテストするためのwaitForXxxxが必ず存在します。

あらかじめ準備されているwaitForXxxxwaitForNotXxxxといったコマンドが自分のニーズを満たしてくれないときはどうすればいいでしょうか? そういう場合のためにwaitForConditionがあります。これを使えば、JavaScriptで書かれたBoolean式を定義して、その式を評価した結果がtrueになるまでSeleniumを待たせることができます。

waitForCondition		script		timeout (in ms)

これは、もっと複雑なAjax作用をテストするときに役に立つはずです。

実は、Seleniumのソースコードの中を漁れば、waitForConditionを使って実装された事前定義のwaitForXxxxwaitForNotXxxxシリーズが全部見つかります。Grig Gheorghiu氏が、このトピックについて「Ajax testing with Selenium using waitForCondition(source)」という素晴らしいブログエントリを書いています。彼がエントリを書いたとき、waitForConditionはただのSeleniumのユーザ拡張に過ぎませんでした(サイト・英語)が、今やそれはSeleniumコアの一部となっています。

まとめ

この手短な記事の中で、私たちはSeleniumというWEB受け入れテストツールを紹介しました。また、waitForXxxxというSeleniumのコマンドを使ったAjaxアプリケーションのテストの仕方について議論し、非同期なテキストの更新というシンプルなAjax作用をSeleniumでテストする方法を実例で示しました。

waitForXxxxについてもっと知りたければ、In Place Editorやオートコンプリート、ドラッグ・アンド・ドロップなどの一般的なAjax作用をテストする方法を教えてくれるサンプルテストケース(サイト・英語)がSeleniumの開発者によって提供されています。これらのサンプルはscript.aculo.usで作成されています。すでによくご存知かもしれませんが、script.aculo.usは有名なAjaxライブラリです。

著者紹介

Jeff Xiong ThoughtWorks勤務。アプリケーション・デベロッパーとして大規模エンタープライズアプリケーションの開発や異種システムの統合に4年の経験をもつ。

Mike Williams 15年の業界経験をもつシニア・デベロッパー。Javaの経験のほか、動的スクリプト言語の熱心なユーザでもある。

Josh Price ThoughtWorks勤務。デベロッパー。JavaとJ2EEによる8年間のエンタープライズシステム構築経験がある。

原文はこちらです:http://www.infoq.com/articles/testing-ajax-selenium

(このArticleは2006年10月2日にリリースされました)

この記事に星をつける

おすすめ度
スタイル

BT