さまざまなアプリケーションが、個々にホストされるモデルからクラウドへと移行するにつれ、信頼性と予測性がより一層重要になります。クラウドでは制御できる要素が限られてくるため、十分にテストされた安定したコードを提供することが今まで以上に重要になります。
大部分の開発者は、彼らが実際にコードをテストするか否かによらず、少なくともどこかの時点でコードのテストについて学習しているはずです。しかし Web 開発者は (通常の開発者以上に) アプリケーションを迅速に提供する必要があるため、単体テストを確実に行うよりも締め切りが優先されることがよくあります。一部の人達は、どのコードに対しても決して単体テストを省略してはならないと考えていますが、それは単体テストがアプリケーションの実際のコンポーネントをテストするものであり、またコードの内部動作を他の開発者に説明するための手段でもあるためです。しかし Web アプリケーションの機能テストとなると、単体テストとはまったく話が異なり、なぜか機能テストはあまり大きな話題になっていません。
この記事では、Web アプリケーションの機能テストを行う際に役立つツールをいくつか説明します。ここでは Google App Engine を使いますが、ここで紹介するテスト手法はすべての Web アプリケーションに適用することができます。また機能テストは (少なくとも最低限のレベルの機能テストは) 非常に簡単かつ容易に行うことができるので、決して機能テストを省略してはならないということについても説明します。この記事では機能テスト用のツールとして、Windmill、Selenium、twill という 3 つを説明します。Windmill と Selenium はどちらも Web の機能テストのためのフレームワークであり、JavaScript アプリケーションと Ajax ( Asynchronous JavaScript and XML) アプリケーションのユーザー・インターフェースのテストを自動化して Web ブラウザーの中で行うことができます。twill は軽量の Web スクリプト・ツールであり、JavaScript 以外の機能テストを行います。
まず、軽量のコマンドライン Web ブラウザーでありスクリプト・ツールでもある twill とデフォルトの Google App Engine プロジェクトを使った機能テストの説明から始めましょう。
最初にアプリケーションへの接続を確立する必要があります。そのためには go コマンドを使います (リスト 1)。ここで、show と入力すると実際の出力が表示されることに注目してください。
リスト 1. show による出力の例
# twill-sh -= Welcome to twill! =- >> go localhost:8087 ==> at http://localhost:8087 current page: http://localhost:8087 >> show Hello World! current page: http://localhost:8087 |
twill にはもう 1 つ、http ステータス・コードをチェックできるという興味深い機能があります。
リスト 2. twill が http ステータス・コードを出力する例
> go http://localhost:8087 ==> at http://localhost:8087 current page: http://localhost:8087 >> code 200 current page: http://localhost:8087 >> code 400 ERROR: code is 200 != 400 current page: http://localhost:8087 |
このコマンドの出力を見ると、twill がエラーを返すのは想定されたのと異なるステータス・コードを取得した場合のみであることがわかります。また twill は、これらのアクションをスクリプトとして実行することもできます。ファイルには任意の名前をつけることができ、そのファイルを twill-sh に渡します。これらのコマンドを test_twill.script というファイルの中に置くと、リスト 3 のようなものが表示されます。
リスト 3. twill の出力の別の例
# twill-sh test_twill.script >> EXECUTING FILE test_twill.script AT LINE: test_twill.script:0 ==> at http://localhost:8087 AT LINE: test_twill.script:1 -- 1 of 1 files SUCCEEDED. |
twill は Web アプリケーションの JavaScript 以外の部分を自動でテストできる便利なツールであり、ここで説明した機能以外にも、変数やクッキー、フォーム、http 認証を処理できるなど、多くの機能を持っています。より高度な使い方については「参考文献」を参照してください。
Selenium は twill よりも本格的なテスト・ツールであり、ブラウザーでクロスプラットフォームのテストを行うことができます。クロスプラットフォームの JavaScript コードを作成することは Web 開発者にとって大変な苦痛です。Web アプリケーションを作成すること自体が非常に困難な上、ようやく完成したと思うと、ある 1 つのブラウザーでしか起こらないよくわからないバグに必ず突き当たってしまうのです。
残念ながら、このタイプのバグを単体テストで検出することはできません。実際、こうしたバグがあるため、そもそもテストすることに意味があるのかと Web 開発者は考えがちなのです。彼らは、テストは通らなければならない試練の 1 つであるが、厳しい期限に間に合わせる上で邪魔になり、信頼のおける作業ですらない、と考えています。では、なぜそんなものを気にする必要があるのでしょう。
Selenium は (他のブラウザー・テスト・ツールと同様に)、そうした問題に対する答えとなります。Selenium を利用すると、各ブラウザーで実行される機能テストを作成することができ、またソース・コードをチェックインするごとに機能テストを実行できる何らかの形式の継続的インテグレーション・システムを実装することができます。そのため、ブラウザーで実行したときに発生する可能性のあるバグを素早く検出することができ、手間をかけてテストをしたことによる成果を即座に得ることができます。
Selenium の最も基本的な機能の 1 つがブラウザーで行われたアクションを記録することです。この機能を利用すると、ブラウザーで行われたアクションを再度テストとして行うことができます。図 1 の例を見ると、ベース URL を入力するためのウィンドウがあることがわかります。このベース URL を出発点として単純にテスト対象の Web サイトのアクションを記録します。この場合は Google App Engine のサイトである http://shell.appspot.com をテストしています (このサイトは Ajax による Python インタープリターのデモを行います)。セッションを記録できると、そのテストを Python でエクスポートし、Selenium を使って実行することができます。
図 1. Selenium の IDE ウィンドウ
テストを実行するためには、単純にそのテストを Python の (あるいは任意の言語の) コードとして保存し、Selenium RC テスト・サーバーをダウンロードして稼働させ、そのテストを実行します。リスト 4 はこのテストの様子を示す例です。
リスト 4. Selenium によるテストの例
from selenium import selenium
import unittest, time, re
class NewTest(unittest.TestCase):
def setUp(self):
self.verificationErrors = []
self.selenium = selenium("localhost",
4444, "*chrome", "http://shell.appspot.com")
self.selenium.start()
def test_new(self):
sel = self.selenium
sel.open("/")
sel.click("link=source")
sel.wait_for_page_to_load("30000")
def tearDown(self):
self.selenium.stop()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main() |
Selenium RC をさまざまなブラウザーで起動し (Selenium RC はテスト用のプロキシーとして動作します)、それから機能テストを実行します。リスト 5 は Selenium RC の出力の例を示しています。
リスト 5. Selenium RC の出力の例
# java -jar selenium-server.jar 01:18:47.909 INFO - Java: Apple Inc. 1.5.0_16-133 01:18:47.910 INFO - OS: Mac OS X 10.5.6 i386 01:18:47.915 INFO - v1.0-beta-1 [2201], [1994] 01:18:48.044 INFO - Version Jetty/5.1.x 01:18:48.045 INFO - Started HttpContext[/,/] 01:18:48.047 INFO - Started HttpContext[/selenium-server] 01:18:48.047 INFO - Started HttpContext[/selenium-server/driver] 01:18:48.055 INFO - Started SocketListener on 0.0.0.0:4444 [output suppressed for space] |
Selenium RC の FAQ をよく読み、さまざまなブラウザーと Selenium RC とがどのようにやり取りするかを理解してください (「参考文献」を参照)。ここで説明したことからもわかるように、Selenium を使うとクロスプラットフォームの機能テストを非常に容易に自動化することができ、しかもサポートされている言語は多数あります (単純な HTML、Java™ コード、C#、Perl、PHP、Python、Ruby など)。
Windmill は Selenium に非常によく似た Web テストのフレームワークですが、両者の間には少し違いがあります。大きな違いの 1 つは Windmill が Python と JavaScript で作成されていることです。Windmill は元々、Chandler (Microsoft® Outlook に対抗するオープンソースの意欲的なプロジェクトです) の Web クライアントをテストするために開発されたものですが、現在も独立したオープンソース・プロジェクトとして継続されています。
Windmill を使い始めるためには、単純に sudo easy_install windmill というコマンドを実行します。すると Windmill テスト・フレームワークがインストールされます。次に windmill firefox と入力すると Windmill IDE が開きます (図 2)。そしてテスト・ページが開きます (図 3)。図 2 を見ると、Selenium とまったく同じように Windmill IDE がアクションを記録することがわかります。アクションが記録されると、そのテスト・ファイルを保存することができます。テスト・ファイルの出力はリスト 6 のようなものです。
図 2. Windmill IDE のウィンドウ
図 3. Windmill のチュートリアル
リスト 6. テスト・ファイルの出力の例
# Generated by the windmill services transformer from windmill.authoring import WindmillTestClient def test_recordingSuite0(): client = WindmillTestClient(__name__) client.click(id=u'recordedClickId') client.click(id=u'textFieldOne') client.type(text=u'foo bar', id=u'textFieldOne') client.click(id=u'btnSub') |
Windmill IDE にはテストを JSON または Python で保存するオプションがあり、この場合は Python で保存しています。次に、実際にテストを実行するためには、単純にコマンドラインからテスト・オプションを指定してテスト・ファイルを実行します。リスト 7 はこの様子を示しています。
リスト 7. テストを実行する
# windmill firefox test=windmill_test.py http://tutorial.getwindmill.com/ Started ['/Applications/Firefox.app/Contents/MacOS/firefox-bin', '-profile', '/var/folders/1K/ 1KgyCzqJHButzT6vq8vwHU+++TI/-Tmp-/tmp_ovtnN.mozrunner', 'http://tutorial.getwindmill.com/windmill-serv/start.html'] Server running... |
この例を Google App Engine アプリケーションや他の任意の Web アプリケーションにも容易に適用することができます。Windmill には優れたドキュメントも用意されており、そこにはプラグインを使って Windmill を拡張する方法などの高度な話題も説明されています。
機能テストは Web 開発プロセスには欠かせません。機能テストを行わない限り、Web 開発は推測ゲームになってしまい、デプロイしても大量にエラーが発生しがちで、リファクタリングを繰り返す羽目になります。
では、機能テストは Web 開発者全員の義務なのでしょうか。私の意見では義務です。すべての Web アプリケーションでテストをするべきであり、特にその Web アプリケーションがクラウド環境で使用される場合には必ずテストをする必要があります。少なくとも Selenium や Windmill、あるいは twill を使って最低限のテストを非常に容易に行えることを考えると、Web アプリケーションの機能テストを行わずに済ませては絶対にいけません。twill の作成者である Titus Brown 博士の言葉を借用すれば、「コードをテストせずに、どうしてそのコードが動作すると言えるのでしょう?」
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Sample Code For This Article | functional_testing_code.zip | 7KB | HTTP |
- 『Python For Unix and Linux System Administration』を活用して独自のコマンドライン・ユーティリティー・セットを Python で作成し、さまざまな問題に取り組んでください。
- 「Getting Started With Google App Engine」は Google App Engine を紹介した記事として好適です。
- 『Google App Engine in Action』を活用し、カスタム・フィーリングを持つアプリケーションを Python で作成してください。
- Google App Engine の正式なドキュメントを読んでください。
- 「Hello World」アプリケーションをゼロの状態から実行させるまでの方法の詳細を解説した記事、Hello World Google App Engine を読んでください。
- Python Tutorial を利用して Python 言語と Python システムの基本的な概念と機能を学んでください。
- Selenium RC サーバーに関する詳細情報を入手してください。
- twill スクリプト言語に関する情報を入手してください。
- Windmill テスト・フレームワークのホームページで Windmill によるテストの自動化について学んでください。
- 『An Introduction to Testing Web Applications With twill and Selenium』を利用して独自の機能テストの作成を即座に開始してください。
- developerWorks の Cloud computing space を利用して、なぜクラウド・コンピューティングが重要なのか、クラウド・コンピューティングを開始する方法、そしてクラウド・コンピューティングを詳しく学べる場を知ってください。

Noah Gift は O'Reilly から出版されている『Python For Unix and Linux System Administration』の共著者であり、また Manning から出版予定の『Google App Engine In Action』も執筆中です。彼は著作者、講演者、コンサルタント、そしてコミュニティーのリーダーとして、IBM developerWorks や Red Hat Magazine、O'Reilly、MacTech などに記事を寄稿しています。彼のコンサルティング会社の Web サイトは http://www.giftcs.com であり、彼が寄稿した記事の大部分は http://noahgift.com で公開されています。彼はカリフォルニア州立大学ロサンゼルス校でコンピューター情報システムの修士号を、カリフォルニア州立工科大学 San Luis Obispo 校で栄養科学の学位を取得しています。また、Apple と LPI 認定のシステム管理者であり、Caltech、Disney Feature Animation、Sony Imageworks などの企業に勤務経験があります。現在はニュージーランドの Weta Digital の業務を行っています。仕事以外の時間には彼の妻である Leah と息子の Liam と時間を過ごし、ピアノ曲を作曲し、マラソンをし、そして神に祈りを捧げています。