先日、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からのフィードバックを受けて、もっと使い易いものになればいいなと考えています。