Web アプリケーションの機能テストを行う

Selenium、Windmill、twill を使って Google App Engine アプリケーションをテストする

クラウドを利用しようとしている人にとって、アプリケーションを信頼できるものにする上ではテストが一層重要になります。オープンソースのツールである Selenium、Windmill、twill を使って自動化された機能テストを行う方法をマスターしましょう。この記事で説明する手法は、Google App Engine やブログ・ソフトウェア、あるいは皆さん独自のアプリケーションにも応用することができます。

Noah Gift , Founder, GiftCS, LLC

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


developerWorks 貢献著者レベル

2009年 3月 10日

はじめに

さまざまなアプリケーションが、個々にホストされるモデルからクラウドへと移行するにつれ、信頼性と予測性がより一層重要になります。クラウドでは制御できる要素が限られてくるため、十分にテストされた安定したコードを提供することが今まで以上に重要になります。

twill と Google App Engine に関する注意

参考文献」には、ゼロの状態から「Hello World」アプリケーションを実行させるまでの方法を詳細に解説した記事を紹介してあります。OS X プラットフォームの場合には、Google App Engine Launcher をダウンロードすれば「Hello World」アプリケーション用のボイラープレート・コードのファイルを作成してくれます。

twill を使い始めるためには、sudo easy_install twill というコマンドを実行すればよいだけです。そのうえでtwill-sh スクリプト・ツールを呼び出せば、対話形式でアプリケーションをテストすることができます。

大部分の開発者は、彼らが実際にコードをテストするか否かによらず、少なくともどこかの時点でコードのテストについて学習しているはずです。しかし Web 開発者は (通常の開発者以上に) アプリケーションを迅速に提供する必要があるため、単体テストを確実に行うよりも締め切りが優先されることがよくあります。一部の人達は、どのコードに対しても決して単体テストを省略してはならないと考えていますが、それは単体テストがアプリケーションの実際のコンポーネントをテストするものであり、またコードの内部動作を他の開発者に説明するための手段でもあるためです。しかし Web アプリケーションの機能テストとなると、単体テストとはまったく話が異なり、なぜか機能テストはあまり大きな話題になっていません。

この記事では、Web アプリケーションの機能テストを行う際に役立つツールをいくつか説明します。ここでは Google App Engine を使いますが、ここで紹介するテスト手法はすべての Web アプリケーションに適用することができます。また機能テストは (少なくとも最低限のレベルの機能テストは) 非常に簡単かつ容易に行うことができるので、決して機能テストを省略してはならないということについても説明します。この記事では機能テスト用のツールとして、Windmill、Selenium、twill という 3 つを説明します。Windmill と Selenium はどちらも Web の機能テストのためのフレームワークであり、JavaScript アプリケーションと Ajax ( Asynchronous JavaScript and XML) アプリケーションのユーザー・インターフェースのテストを自動化して Web ブラウザーの中で行うことができます。twill は軽量の Web スクリプト・ツールであり、JavaScript 以外の機能テストを行います。

twill を使った機能テスト

Easy Install

Easy Install は Python パッケージをローカルに、あるいはネットワーク上にインストールする際に役立つツールです。ほとんどの場合、easy_install コマンドはネットワークからパッケージをインストールする場合に使われます。

まず、軽量のコマンドライン 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 を使った機能テスト

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 ウィンドウ
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

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 のウィンドウ
Windmill IDE のウィンドウ
図 3. Windmill のチュートリアル
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 Articlefunctional_testing_code.zip7KB

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=380629
ArticleTitle=Web アプリケーションの機能テストを行う
publish-date=03102009