2009年12月に JUnit 4.8 がリリースされました。このリリースではテストケースにカテゴリを付与することで、実施するテストを選択できるようになっています。カテゴリのために以下の2つのクラスが追加されています。
Categories とは
Categories は、テストスイートによるテストケースの実行指定を細かく制御できる仕組みです。テスト対象のメソッドやクラスをカテゴリにてマークすることで、テストスイートから実行する対象を細かく制御できるようになります。
Categories の使い方
カテゴリを使用するには、インターフェース、またはスーパークラスにてカテゴリのマーカーを作成します。例えばテストケース毎に、短時間で終わるテストと、長時間かかるテストの2つのカテゴリを用意する場合、以下のように2つのカテゴリとしてマーカーインターフェースを作成します。
public interface FastTests { } public interface SlowTests { }
テストケースでは、以下のように @Category アノテーションによりメソッドやクラスにカテゴリを付与します。
public class A { @Test public void a() { fail(); } @Category(SlowTests.class) @Test public void b() { System.out.println("A.b()"); } }
@Category({SlowTests.class, FastTests.class}) public class B { @Test public void c() { System.out.println("B.c()"); } }
テストスイートでは、以下のように @RunWith アノテーションで Categories.class を指定し、@IncludeCategory アノテーションで、このテストスイートに含めるカテゴリを選択します。
@RunWith(Categories.class) @IncludeCategory(SlowTests.class) @SuiteClasses( { A.class, B.class }) public class SlowTestSuite { }
上記テストスイートでは、@SuiteClasses として A.class と B.class を指定していますが、@IncludeCategory にて SlowTests.class のみを指定しています。そのため実行されるテストケースは、A.b と B.c が実行され、A.a は実行されません。
@ExcludeCategory にて除外するカテゴリの指定もできます。
@RunWith(Categories.class) @IncludeCategory(SlowTests.class) @ExcludeCategory(FastTests.class) @SuiteClasses( { A.class, B.class }) public class SlowTestSuite { }
このテストスイートでは、FastTests.class が除外されるため、A.b は実行されますが、A.a と B.c は実行されません。
public class B implements SlowTests, FastTests { @Test public void c() { System.out.println("B.c()"); } }
カテゴリの階層化
カテゴリはマーカーインターフェースの継承階層を作ることにより実行を細かく制御できます。例えば前述の例に SlowTests を継承する SimpleSlowTests というマーカーインターフェースを加えます。
public interface FastTests { } public interface SlowTests { } public interface SimpleSlowTests extends SlowTests { }
合わせて A.b() のカテゴリを SimpleSlowTests.class として指定します。
public class A { ・・ @Category(SimpleSlowTests.class) @Test public void b() { System.out.println("A.b()"); } }
この時、以下のテストスイートでは、SlowTests のサブタイプである SimpleSlowTests によってカテゴリ指定された A.b() も実行されます。
@RunWith(Categories.class) @IncludeCategory(SlowTests.class) @SuiteClasses( { A.class, B.class }) public class SlowTestSuite { }
以下のようにすると、もちろん A.b() だけが実行されます。
@RunWith(Categories.class) @IncludeCategory(SimpleSlowTests.class) @SuiteClasses( { A.class, B.class }) public class SlowTestSuite { }