JUnit 4.8 の新機能 Categories とは


2009年12月に JUnit 4.8 がリリースされました。このリリースではテストケースにカテゴリを付与することで、実施するテストを選択できるようになっています。カテゴリのために以下の2つのクラスが追加されています。

  • org.junit.experimental.categories.Categories
  • org.junit.experimental.categories.Category

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 { }