2011年3月23日 22:37

Scenic3でAppUrlsのテストを簡単に行う #slim3 #scenic3

先日のTDDBCでGitを使ったのでためしに使ってみるテスト


Scenic3slim3を薄くラップして1つのPageクラスに複数のControllerを持たせることのできるフレームワークです。

Controllerクラスが増えすぎずStrutsライクにコードを書けるため結構使いやすいのですが、Pageクラスを追加する度にAppUrlsにも対応するMatcherクラスを追加しないといけないのが難点です。

package sample.page;

@Page("/")
public class FrontPage extends ScenicPage{

    // some method

}
package sample.controller;

public class AppUrls extends UrlsImpl {
    public AppUrls() {
        add(FrontPageMatcher.get());
    }
}
結構忘れがちなのでたまにページにアクセスできなくてハマります

そこで、JUnitを使ってAppUrlsに全てのMatcher.get()が書かれているかを動的に調べるユーティリティっぽいのを作ってみました
package sample.controller;

public class AppUrlsTest extends AppUrlsTester {
    @Test
    public void checkPageMatcher(){
        if(AppEngineUtil.isProduction()){
            // Production環境ではクラスパスがとれないためテストしない
            return;
        }
        assertAppUrls("sample", new AppUrls());
    }
}
こんなテストクラスを1つ作っておくだけで、Pageが追加された時に自動的にAppUrls内のMatcher.get()の記述かあるかどうかを調べてくれます。ビバ自動化

仕組み
  • クラスパス配下を全て検索してPageクラスを検出する(ScenicPageを継承していて、かつ@Pageがついているクラス)
  • 検出したPageクラスに対応するMatcher.get()のtoString()の結果(パス情報)が全てAppUrlsに含まれているかを調べる

欠点
  • 任意のPageクラスだけ除外ということができない
  • Production環境上ではクラスパスが取得できないため、ローカル上でしかテストできない。
    クラスファイルを列挙するためにファイルシステムにアクセスしていますが、[Java] 指定パッケージ内のクラス一覧を取得するサンプルのやり方だとjavax.tools.*がappengineのSDKでサポートされていないためローカルで動かすこともできません
  • UrlsImplの実装に依存しているため、UrlsImplの仕様が変わるとアウト
  • ろくなドキュメントがない。ソース嫁

そんなわけで便利なテストクラスですが欠点もあるため使いたい場合は自己責任で使ってください


動作確認環境
  • Google App Engine SDK 1.4.2
  • Slim3 1.0.9
  • Scenic3 0.4.2

ソース
main以下を適当にインポートして使ってください


3/24追記

Scenic3の作者のshuji_w6eさんが僕のソースをヒントにAppUrlsの自動テストを実装してくれました。ありがとうございますー(0.5.0で対応予定)

Scenic3のAppUrlsに関するテスト - やさしいデスマーチ