SE情報技術研究会’s blog

http://se-info-tech.connpass.com

2016-01-10 『JUnit実践入門』読書会(第5章)の振り返り

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

第5章 テストランナー

  • テストクラスに定義されたテストケースをどのように実行するのか制御を行うクラス
  • 通常使うものに対してはJUnitに標準で用意されている
  • テストランナーは@RunWithを使ってテストクラスごとに設定する
  • org.junit.runners.JUnitは標準的なテストランナークラス
  • @RunWithをつけないとJUnit4が自動で使われる
  • 個々のテストケースの拡張には第9章のルールを使う

コマンドラインからの実行

  • junit.runner.JUnitCoreを使用する
  • 実行時いはクラスパスにJUnitのJARが指定されている必要がある
  • テストクラスのmainメソッドを実装する
public static void main(String[] args) {
  JUnitCore.main(CalcTest.class.getName());
}

JUnit4

  • テストクラスの実行すべき全テストケースを実行するテストランナー
  • JUnit4テストランナーは原則1つのテストクラスが対象

次のテストケースを収集し実行する

  • publicのテストメソッド
  • @Testがついている
  • 戻り値がvoidで引数を持たない

privateにしたり戻り値をintに変えたりして試してみたら、テストケースとして認識されず実行されなかった。

Suite

  • 複数のテストクラスを束ねて実行するテストランナー
  • クラス名には慣例として「~Tests」としている
  • テストクラスに@RunWith(Suite.class)に加えて@SuiteClassesを追加する
  • @SuiteClassesには対象となるテストクラスを指定する
@RunWith(Suite.class)
@SuiteClasses({ CalculatorTest.class, CalcTest.class })
public class AllTest {
}
  • クラスの中身の実装は不要

実運用では

  • テストスイートはテストクラスを手動で追加しないといけないの手間
  • Marvenなどで多くのツールJUnitをサポートしていて、柔軟なテストケース収集ができ実行できる
  • ツールを使えば「Test」で終わるすべてのクラスを実行などテストスイートを使わなくても行える
    → そのため命名規約は大事

Enclosed

  • 構造化したテストクラスのテストを実行するテストランナー
  • テストランナーとしてネストしたクラスを定義しテストケースは各ネストしたクラスに定義する
  • テスト対象のオブジェクトの状態毎などにネストしたテストクラスを生成することが可能
    → テストケース実行前の状態の設定などの処理を共通化することが可能(setUpメソッド

Theories

  • パラメータ化テストをサポートするテストランナー
  • テストクラスに@RunWith(Theories.class)をつける
  • テストメソッドで使うパラメータのデータに@DatePointsをつける
  • パラメータを使うテストケースに@Theoryをつける
  • パラメータとなるデータはケースごとの配列やListにする
  • パラメータとなるデータはpublicである必要がある
  • テストケースのメソッドの引数にケースごとのパラメータが渡される
@RunWith(Theories.class)
public class CalcTheories {
  
  @DataPoints
  public static final int[][] VALUES = { //
      { 0, 0, 0 }, //
      { 0, 1, 1 }, //
      { 1, 0, 1 }, //
      { 3, 4, 7 } //
  };
  
  @Theory
  public void add(int[] values) {
    Calc sut = new Calc();
    int actual = sut.add(values[0], values[1]);
    assertThat(actual, is(values[2]));
  }
}

Categories

  • テストケースをカテゴリ化し、カテゴリごとに制御するためのテストランナー
  • Suiteクラスを継承している
  • カテゴリ付けのためのマーカーインターフェイス(実装は不要)が必要
  • カテゴリ付けするテストケースに@Categoryをつける
  • @RunWith(Cateogries.class)@SuiteClassesをつけたテストスイートを用意する
  • テストスイートにカテゴリごとの条件のアノテーションをつける

テストケース

  @Test
  @Category(SlowTests.class)
  public void fastTest2() {
    fail();
  }

テストランナー

@RunWith(Categories.class)
@ExcludeCategory(SlowTests.class)
@SuiteClasses(SlowAndFastTest.class)
public class CategoriesTests {

}

org.junit.experimentalパッケージ

  • 実験のためのパッケージ
  • 今後、仕様変更やパッケージ移動や削除などがありうる

JUnit Lambda では色々変わってるらしい

参照: Developer IO JUnit5はどこに向かうのか? http://dev.classmethod.jp/testing/unittesting/where-is-junit5-aheaded/