理系学生日記

おまえはいつまで学生気分なのか

テスト前提が満たされている場合にのみJUnitのテストケースを実行したい

Java で JUnit のテストコードを書く場合、テスト実行環境がこういう前提を満たした場合にのみ、このテストを実行させるようにしたい、というようなケースが多々あります。 例えば、

  • テスト実行環境の OS に依存する
  • テスト実行環境における特別なソフトウェアのインストール有無に依存する

といったようなケースです。 このように、前提条件が満たされるか否かによってテストの実行是非を制御するようにしたい場合、Assume を利用するのが簡単です。

Assume

Assume クラスは JUnit に付随してくるクラスで、Assert と対を成すようなメソッドを持っています。 下記にいくつか抜粋します。

public static void assumeTrue(boolean b);
public static void assumeFalse(boolean b);
public static void assumeNotNull(Object... objects);
public static <T> void assumeThat(String message, T actual, Matcher<T> matcher);

これらのメソッドは、いずれも「前提条件」を記述するようになっており、前提条件が満たされれば何も起こしません。 一方で、前提条件が満たされなかった場合、AssumptionViolatedException を送出するようになっています。この AssumptionViolatedException は、一般に TestRunner で特別視され、JUnit の TestRunner だと当該例外発生時はそのテストを無視する、という振舞になります。 これを利用すれば、上記のような OS 依存、ソフトウェアインストール状況依存のテストも、問題なく記述できるようになります。

簡単なサンプルとして、Mac 以外の OS でのみ実行するテストを記述すると以下のようになります。

package com.kiririmode.blog;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeFalse;

import org.junit.Test;

public class AssumeTest {

    @Test
    public void Mac以外のOSで実行するテスト() {
        // テスト実行環境が Mac でない場合はテストを実施しない
        assumeFalse(isMac());
        assertThat(System.getProperty("os.name"), is("Mac OS X"));
    }

    /**
    * 実行環境が Mac かどうかを判定する
    *
    * @return 実行環境が Mac の場合に true
    */
    private boolean isMac() {
        return System.getProperty("os.name").contains("Mac");
    }
}

テストクラスに記述された全テストケースがそういう環境依存のテストであるならば、@Before あるいは @BeforeClass を付与したメソッドで assume* を使う方が効率的になります。

環境依存テストの別解

上述のような「前提条件」をテストクラス横断で行いたい場合は、都度前提条件を記述するよりは、前提条件をひとつの TestRule として記述した方が省力化が図れます。 このあたりのことは、JUnit 実践入門の 「9.3. カスタムルールの作成」にシャレたサンプルが掲載されているので、参考にすると良いと思います。