2013年12月24日火曜日

JnarioでJavaのTDD

この記事は、TDD Advent Calendar 2013 の第23日目(の一日遅れ)です。
昨年のアドベントカレンダー以来、記事を書いていないという事実に、本人も驚きです。

あなたはJavaでTDDしてる人ですね

そうじゃなくても構いませんが、一応、そういう人が対象です。
または、Javaでテスト気軽に書きたいけど面倒で〜、という方も対象です。
あるいは、Javaでテストとかただの二重苦だろw、という方も対象です。

偉大なJUnit、しかし苦行

Javaでテストと言えば、プログラマに開発者テスト文化やTDDを根付かせた偉大なツール、JUnitがあります。
JUnitの最大の利点は、Javaプログラマがその知識のままテストを書けることですが、それと同時に、Java自体の表現力の弱さも100%享受してしまうのであります。脱初心者後に、JUnitで沢山のテストを書き続けるというのは、ちょっとした苦行でしょう。

Jnarioという選択

TDDの原理は道具と無関係ですが、実践には道具の選択が大切です。
JUnitでテストデビューを飾った後は、他の効率の良い道具を試してみましょう。
GroovyのSpockや、Cucumberを選択するなど、動的型言語由来の製品を使う例も聞きますが、今回おすすめの製品は、Jnarioです。

Jnarioには、以下のような特徴があります。

  • SpecとFeature、両方のテストDSLをサポート
  • Spec/Feature専用のEclipseエディタ
  • SpecとFeatureの両方が、完全なJUnit(Java)コードにコンパイルされる
  • Xtendと同じ、型推論やラムダなどの記述能力を持つ静的型の式言語 (Xbase)
  • テスト失敗時の詳細な値のレポート
  • あわせてJava自体の開発効率向上に使いたい => Xtend

Jnarioのインストール

Jnarioを使うには、Eclipseプラグインを使うのが一番簡単です。
Eclipse Keplerに、Jnarioの更新サイトからプラグインをインストールしましょう。
更新サイト => http://www.jnario.org/updates/releases/

※同時にXtendも入るので、ぜひXtendもご利用ください


Specの作成

Eclipseの新規作成ウィザードで、Specを作ります。

Jnarioのライブラリを取り込むために、Ctrl+1 (Quick Fix)で取り込みます。

Specの記述

テスト対象クラスのSpec内容を記述します。
※1 テストに対応するプロダクションコードは別途作成済みとします
※2 例ではXtendでプロダクションコードを作成しています
※3 プロダクションとテストの両コードに対応するJavaコードが生成されています


Run As -> JUnit Test

Specを実行します。実行するには、Run As -> JUnit Testを行うだけです。

失敗テストの解析

power-assertの様に、実値式の各セグメントの解析内容を出力してくれます。

Featureの作成

Eclipseの新規作成ウィザードで、Featureを作ります。

Featureの記述 (ステップなし)

今回はFeatureとして適切な例ではありませんが、上記のSpecと同様のテスト内容にしてみます。
まずはステップなしの状態で、そのままテスト実行してみます。
テスト実行するには、Specと同様、Run As -> JUnit Testです。

Featureの記述 (ステップあり)

Featureにステップを記述して、テストを実行してみます。

解説

describeとcontextで、簡単に構造化できます

この辺りは常識的ですね。
describeは複数階層記述できます。contextは、最後の階層で使えます。
describeに指定する情報は、説明文字列か、またはクラス名です。
説明文字列は、単にテストの内容説明的なものです。
クラス名を記述した場合は、デフォルトコンストラクタで暗黙のsubjectが生成されます。

factで、簡単にテストブロックを記述できます

factは、テスト構造の中に、何度でも記述できるテストです。
factに与えられるものは、次の3つです。

  • 評価式
    fact  actual => expected (評価式)を書くと、それが直接テストになります。
    評価式はこの形式以外もありますが、一番便利なので最初に覚えてください。
  • ブロック
    fact  {...} の形式で書くと、テスト内容をブロックで記述できます。
    初期化や複数の評価式を組み合わせたい時は、この形で書きます。
  • 説明文とブロック
    fact  "説明文" {...} の形式で書くと、テストブロックは上記と同様に評価されます。
    説明文はそのまま、JUnitのテスト一覧に表示されます。

beforeで、fact共通の初期化などを行えます

ごく普通のことですが、JUnitより簡潔に記述できるのが良いです。

その他のテクニック

その他にも、Jnarioには強力なことを簡単に行う仕組み沢山あります。

  • Example tableによる、簡単なParameterized Test
  • before/afterによる簡単にsetup/teardown (before all/after allもあり)
  • before/after/ユーティリティを共通化できる spec extension 機構
  • JUnitのRule定義も可能
  • 簡単なカスタムアサーション
  • (Feature) 複数シナリオに共通のバックグラウンドシナリオ
  • (Feature) シナリオ毎のbefore/after
  • (Feature) 他シナリオのステップ参照 (import & Given文一致)
詳しくは、Jnarioのサイトを見てみてください。

まとめ

Jnarioを使うと、今日からすぐに、(恐らく) JUnitよりもずっと簡単に、Javaでテスト/TDDをできるようになります。
ちなみに、私が以前やっていたJava開発チームでも、日常的に、XtendとJnarioを使って開発/テストを行っていました。

皆様も、ぜひJnarioのSpecとFeatureをお試しください。