技術っぽいことを書いてみるブログ

PythonとかVue.jsとか技術的なことについて書いていきます。

いまさらながら…JUnit5についてまとめておく(パラメータ化テスト編)

背景

JUnit5のパラメータ化テストが便利なのでまとめておきます・・。

パラメータ化テストとは…

テストケースとテストデータを分離し、同じテストメソッドを複数のパラメータで再利用して使う方法。

JUnit4時代では、Theoriesクラスを指定することでパラメータをテストメソッドを定義できるようになっていたが、
JUnit5では、Argumentsクラスと@MethodSourceによりより簡潔になったと思います…。

パラメータ化テストの方法

@ParameterizedTest

  • パラメータ化テストを行うテストには、@Testではなく、@ParameterizedTestを付与する

@MethodSource

  • テストメソッドのパラメータは、@MethodSourceでパラメータを生成するメソッド名を指定する
  • こんな感じ
@ParameterizedTest
@MethodSource("test2_testData")
void test(String displayName, String expected, String moji) {
  assertEquals(expected,  moji);
}

Stream<Arguments> test2_testData(){
  return Stream.of(
    Arguments.of("Test1", "aaa", "aaa"), 
    Arguments.of("Test2", "BBB", "BBB")
  );
}
  • テストデータ生成メソッドを複数指定する場合は、@MethodSource({"test_testData1", "test_testData2"}) こんな感じ。

Argumentsについて

  • @ParameterizedTestを付与したメソッドの引数は、ArgumentsクラスのStreamで渡す
  • Argumentsクラス
    • 第1引数はテスト名となる
    • 第2引数以降がテスト時のパラメータとなる

テストメソッドについて

  • Argumentsクラスに設定した値を受け取れる形で、メソッドを定義する

パラメータ化テストの例

  • テスト対象
public enum Janken {
    GU(){
        @Override
        boolean isWin(Janken aite) {
            return aite == TYOKI;
        }
    },TYOKI(){
        @Override
        boolean isWin(Janken aite) {
            return aite == PA;
        }
    },PA(){
        @Override
        boolean isWin(Janken aite) {
            return aite == GU;
        }
    };

    abstract boolean isWin(Janken aite);
}
  • テストクラス
import static org.junit.jupiter.api.Assertions.*;

import java.util.stream.Stream;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;

class JankenTest  {
    @ParameterizedTest
    @MethodSource({"test2_testData", "test2_testData2"})
    @DisplayName("じゃんけんの勝ち判定")
    void test2(String displayName, boolean expected, Janken janken, Janken aite) {
        assertEquals(expected, janken.isWin(aite));
    }

    static Stream<Arguments> test2_testData(){
        return Stream.of(
                    Arguments.of("GUが勝ち", true, Janken.GU, Janken.TYOKI),
                    Arguments.of("GUが勝ちでない", false, Janken.GU, Janken.PA),
                    Arguments.of("GUが勝ちでない", false, Janken.GU, Janken.GU),
                    Arguments.of("TYOKIが勝ち", true, Janken.TYOKI, Janken.PA),
                    Arguments.of("TYOKIが勝ちでない", false, Janken.TYOKI, Janken.TYOKI),
                    Arguments.of("TYOKIが勝ちでない", false, Janken.TYOKI, Janken.GU)
                );
    }

    static Stream<Arguments> test2_testData2(){
        return Stream.of(
                Arguments.of("PAが勝ち", true, Janken.PA, Janken.GU),
                Arguments.of("PAが勝ちでない", false, Janken.PA, Janken.TYOKI),
                Arguments.of("PAが勝ちでない", false, Janken.PA, Janken.PA)
            );
    }
}
  • 実行結果

所感

JUnit5のパラメータ化テストは、簡潔にかけるので、かなり使えると思います。