先日、Kent Beckのインタビュー記事 Developer Spotlight: Kent Beckを読んでいたら、以下のような記述に出会いました。
Erich Gamma and I are working on a new JUnit release that will mark its first significant architectural changes since JUnit was very young.
むむっ、significant architectural changesとはどのようなものなのでしょうか。
興味を持ってsfの中を探してみると...Version4というブランチがありました。もう開発が始まっているんですね。さっそくチェックアウトしてみました。
$ cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/junit co -rVersion4 junit
少しいじってみたら色々分かってきましたので、現時点での所見をまとめてみたいと思います。ただし、JUnit4はまだ開発が始まったばかりのようなので、あくまで現時点でのレポートです。これからもいろいろ変更され、もっと便利になってゆくでしょう。期待しながらHEADを追いかけたいと思います。
またJUnit4の変更速度は比較的ゆっくりで、週末しかコミットされていないように見受けられます。Kent BeckもErich Gammaも忙しいのでしょう(当り前か)。
追記: どうやら二人でリモートペアプロしているみたいです。
と、ここまで書いていたら、かくたにさんの日記でErich Gammaも発言していることを知りました。Kent Beck,Erich Gamma二人とも発言を始めたんですね。
JUnit4の目指すもの
to-do.txtに以下の記述があります。Theme: lower the barriers to entry and enable more sophisticated testing
「取っ付き易く、かつ洗練されたテストを可能にする」でしょうか。
ここにも「易しさと優しさ」ですね。
JUnit4の変更点
JUnit4の最大の変更点は「アノテーションの導入」です。significant architectural changesとは、多分アノテーションの導入のことでしょう。ではアノテーションの導入によって何が得られるでしょうか。現時点で考えられる利点を挙げてみます。
- クラスjunit.framework.TestCaseを継承する必要がなくなる
- テストメソッド名を"test"で始めなくてよくなる
- "setUp","tearDown"というメソッド名の縛りも不要になる
- テストクラス単位の初期化が明確で簡単になる
- 例外のテストが簡略化される
- (おそらく)特定のテストを無視させることができるようになる
- (おそらく)テストにカテゴリをつけることができるようになる
具体例はサンプルを見た方が早いと思いますので、サンプルを書いてみました。
1 package com.example.junit4; 2 3 import static org.junit.Assert.assertEquals; 4 import static org.junit.Assert.assertTrue; 5 6 import java.util.Arrays; 7 import java.util.List; 8 9 import junit.framework.JUnit4TestAdapter; 10 11 import org.junit.After; 12 import org.junit.AfterClass; 13 import org.junit.Before; 14 import org.junit.BeforeClass; 15 import org.junit.Test; 16 17 18 public class Junit4SampleTest { 19 20 private String sampleStr; 21 private static List<String> hugeData; 22 23 public static junit.framework.Test suite() { 24 return new JUnit4TestAdapter(Junit4SampleTest.class); 25 } 26 public static void main (String... args) { 27 junit.textui.TestRunner.run (suite()); 28 } 29 30 @Before 31 public void インスタンス単位の前準備() { 32 System.out.println("■インスタンス単位の前準備"); 33 this.sampleStr = "Hoge"; 34 } 35 36 @BeforeClass 37 public static void テストクラス単位の前準備() { 38 System.out.println("▲テストクラス単位の前準備"); 39 hugeData = Arrays.asList("Per","Class","Setup"); 40 } 41 42 @After 43 public void インスタンス単位の後始末() { 44 System.out.println("□インスタンス単位の後始末"); 45 } 46 47 @AfterClass 48 public static void テストクラス単位の後始末() { 49 System.out.println("△テストクラス単位の後始末"); 50 } 51 52 @Test 53 public void 小文字に変換できる() { 54 assertEquals("hoge", this.sampleStr.toLowerCase()); 55 } 56 57 @Test 58 public void 大きめのデータにアクセスする() { 59 assertTrue(hugeData.contains("Per")); 60 } 61 62 @Test (expected=StringIndexOutOfBoundsException.class) 63 public void 範囲外のインデックスにアクセスすると例外が発生すること() { 64 this.sampleStr.charAt(30); 65 } 66 }
実行例
▲テストクラス単位の前準備 .■インスタンス単位の前準備 □インスタンス単位の後始末 .■インスタンス単位の前準備 □インスタンス単位の後始末 .■インスタンス単位の前準備 □インスタンス単位の後始末 △テストクラス単位の後始末 Time: 0.044 OK (3 tests)
JUnit4のアノテーションについて
30行目の@Beforeアノテーション、42行目の@AfterアノテーションはそれぞれsetUp,tearDownメソッドの仕事を果たします。36行目の@BeforeClassアノテーション、47行目の@AfterClassアノテーションは、テストクラス単位での初期化処理と終了処理を司ります。これまでjunit.extensions.TestSetupを使って行っていた作業はここで書くようになるでしょう。個人的には現時点で最もJUnit3系との差が大きい部分だと思います。クラス単位の初期化が非常に書きやすくなりました。
@Testアノテーションはその名の通りテストメソッドを意味するアノテーションです。JUnit4は@Testの付いたメソッドをテスト対象と認識します。なお3,4行目でstatic importを行っているので、TestCaseを継承しなくてもテストメソッドの中で普通にassertEqualsやassertTrueを使用できます。
62行目では
@Test (expected=StringIndexOutOfBoundsException.class)
という書き方をしています。これは例外発生をテストする書き方で、従来では
public void test範囲外のインデックスにアクセスすると例外が発生すること() { try { this.sampleStr.charAt(30); fail(); } catch (StringIndexOutOfBoundsException expected) { } }
と書いていたようなテストの新しい書き方となります。
JUnit4のこれからを予想する
to-do.txtを見ていくと何点か面白そうな記述があります
@Ignore
@Ignoreアノテーションがついたメソッドはおそらく「無視されたことがレポートされる」ようになると思われます。NUnitの「黄色」のような状態でしょうか。この機能はNUnitの羨ましい機能のひとつでした。
test categorization & filtering (<- seems like a runner issue) @Category(short, integration) @Test(category=windowsOnly)
テストのカテゴライズが行われることになりそうです。ただ、書法はまだ悩んでいるみたいです。どういう判断がされるかを知ることが出来るのもHEAD追っかけの醍醐味と言えるのではないでしょうか。
追記: Erich Gammaはhttp://www.rojotek.com/blog/rob/archives/000076.htmlのコメント欄にて、
We are open for feedback and Kent and I intend to start blogging on our experiences soon.
と発言しています。楽しみになってきました。
個人的にはNUnitやTestNGからのフィードバックを受けて、もっと使い易いものになればいいなと考えています。