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

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

Comments

はじめに

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

大部分の開発者は、彼らが実際にコードをテストするか否かによらず、少なくともどこかの時点でコードのテストについて学習しているはずです。しかし 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 を使った機能テスト

まず、軽量のコマンドライン 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 ウィンドウ
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 のウィンドウ
Windmill IDE のウィンドウ
図 3. Windmill のチュートリアル
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 博士の言葉を借用すれば、「コードをテストせずに、どうしてそのコードが動作すると言えるのでしょう?」


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

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