クライアントサイドWebアプリケーションに特化したミューテーション解析ツール - AjaxMutator
近年のWebアプリケーションは、クライアント(ブラウザ)側にAjax技術が利用されています。例えば、GoogleやFacebookなどもWebアプリケーションのクライアント側にAjax技術を採用しています。Ajax技術は下記3つの特徴を持ち、Webアプリケーションの応答性を向上させるために役立ちます。
- ユーザイベント:ユーザからの入力をイベント駆動的に処理
- 非同期通信:サーバと非同期的にデータを送受信
- 動的なページ要素の操作:ページ遷移を伴わず表示情報を更新
我々はこれら3つの特徴を分析し、WebアプリケーションにおけるAjaxプログラムに特化したミューテーション操作を定義しました(表2)。これらの操作を実装したAjaxMutatorのソースコード は、GitHubで公開しています。
AjaxMutatorの仕組みを簡単に説明します(図5)。ミューテーション解析では、ソースコードの一部を改変することで欠陥を埋め込みますが、Webアプリケーションのソースコードはサーバ側に配備されており直接改変することはできません。そこでAjaxMutatorは、自前のProxyサーバを介すようテストケースを実行することで、テスト対象のソースコードをローカルファイルシステムにいったん保存します(Recordモード)。次に、保存したソースコードに表2のミューテーション操作を適用することで、欠陥を含むAjaxプログラムを生成します(Rewriteモード)。このようにして、AjaxMutatorはWebアプリケーションに対するミューテーション解析を実現しています。
では、AjaxMutatorを使ってみましょう。本稿ではテスト対象アプリケーションとして、OSSのクイズライブラリであるQuizzy(図6)を利用します。
なお、記事中のソースコードはGitHub上で公開しています。併せて参照してください。
AjaxMutatorの導入
AjaxMutatorの実行バイナリはMavenレポジトリから取得可能です。まずはEclipseなどを用いてMavenプロジェクトを作成しましょう 。Mavenプロジェクトでは、利用するライブラリなどはPOM(Project Object Model)ファイルに記述します。AjaxMutatorの実行バイナリが配備されているレポジトリを登録し、依存関係にAjaxMutatorに追加します。また、AjaxMutatorはJDK 1.7以降をサポートしているためコンパイラ情報も明記します(図7)。
設定ファイルの作成
AjaxMutatorを利用するためには下記の2つのファイル「localenv.properties」と「quizzy.properties」を作成し、クラスパスの通ったディレクトリに配備してください。
localenv.propertiesの作成
このファイルには、テスト対象アプリケーションに依存しない設定情報を記述します。
-
テストの実行環境であるWebブラウザのバイナリへのパス
AjaxMutatorはFirefoxとPhantomJSに対応しており、それぞれfirefox-binまたはphantomjs-binを用いて設定できます。 - ProxyサーバがListenするポート番号
quizzy.propertiesの作成
このファイルには、テスト対象アプリケーションに依存する設定情報を記述します。
- Recordモード時にソースコードを保存するディレクトリへのパス。Rewriteモード時にも同じディレクトリを参照しミューテーション操作を適用します。
- テスト対象Webアプリケーションが配備されているURL。
- ミューテーション操作を適用するJavaScriptファイルへのURLからの相対パス。
- Proxyサーバのモード。RecordとRewriteモードを切り替える際に、それぞれram recordとram rewriteに編集する必要があります。また、単純にテストケースを実行する(ソースコードの保存や書き換えをしない)場合は、ramを設定します。
テストケースの実装
テスト実行時に都度Proxyサーバを起動・停止することは手間がかかります。そこでAjaxMutatorは、その作業を自動化する便利機能を提供しています。この便利機能を利用するために、テストケースを実装するJavaクラスにWebAppTestBaseを継承しましょう。図10にこのクラスの利用例を示します。ここでは主に下記3つの機能が動作します。
- @BeforeClass:このテストスイートに含まれるテストケースが実行される前に、設定ファイルを読み込んだり、Proxyサーバを立ち上げたりします。
- @Before:各テストケースが実行される前に、Webブラウザ上でURLを開き、ページの表示が完了するまで待機します。
- @AfterClass:このテストスイートに含まれるテストケースの実行が完了した後に、WebブラウザやProxyサーバを停止します。
これらの機能は、汎用的に動作するよう設計してあります。テンプレートとして利用してみてください。
簡単なテストケースを1つ実装してみましょう。図11では、showQuizDescriptionメソッドにおいて、Quizzyで「クイズを選択し、その説明文が期待通りか」確認するテストケースを実装しています。Proxyサーバの設定をRecordモードに変更しテスト実行することで、Quizzyのソースコードファイルがローカルファイルシステムへ保存されます(図12)。