今回はJUnitを学習するにあたって勉強した、アサーション等をまとめることにします。


代表的なアサーションメソッド


assertEquals

2つの値を比較し、同じ場合はテスト成功

assertEquals(a, b);

assertEquals(a, b, "失敗の場合のメッセージ");

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class SimpleCalculatorTest extends SimpleCalculator {
	@Test
	void testCompare() {
		// 2つの値
		int expectedNum = 4;
		int actualNum = 3;
		// 比較
		assertEquals(expectedNum, actualNum, "expectedNum:" + expectedNum + ", actualNum:" + actualNum + "なので違います。");
	}
}
失敗した場合は以下のように表示されます。

assertTrue, assertFalse

条件がTrue または Falseの時にテスト成功

boolean flag = true;

assertTrue(flag);

assertTrue(flag, "失敗の場合のメッセージ");


失敗した場合は以下のように表示されます。

assertAll

複数のアサーションをまとめて実行し、それぞれの結果を一括して検証する

int result = 10;

// 複数のアサーションをまとめて検証

assertAll("失敗時のメッセージ",

() -> assertEquals(10, result),

() -> assertTrue(result > 0),

() -> assertFalse(result < 0)

);


失敗した場合は以下のように表示されます。

assertThrows

第一引数には検出する例外を、第二引数にはラムダ式またはメソッド参照を渡します。
もし、指定した例外がスローされなかった場合、テストは失敗します。
うになっています。

・Java側

public float div(int x, int y) {
		if (y == 0) throw new IllegalArgumentException("0で除算はできません。");
		return (float)x / y;
	}

・JUnit側

@Test
void testDivException02() {
	// オブジェクト生成
	SimpleCalculator simCal = new SimpleCalculator();
	// ラムダ式で、0で除算する。
	assertThrows(IllegalArgumentException.class, () -> simCal.div(9, 0));
}

実行された結果は以下のようになります。

代表的なアノテーション@

@Test

テストメソッドにつけるアノテーションです。
@Testが無いものは、JUnitの実行が選択肢に出てこないです。

@Testをつけた場合

@DisplayName

テストメソッドやテストクラスに表示名を設定するために使用されます。

@DisplayName("クラス1")

class SimpleCalculatorTest extends SimpleCalculator {

@Test

@DisplayName("テストケース1-1-1")

void testDivException01() {

// オブジェクト生成

SimpleCalculator simCal = new SimpleCalculator();

// ラムダ式で、0で除算する。

assertThrows(IllegalArgumentException.class, () -> simCal.div(9, 0));

}

@Test

@DisplayName("テストケース1-1-2")

void testDivException02() {

// オブジェクト生成

SimpleCalculator simCal = new SimpleCalculator();

// ラムダ式で、0で除算する。

assertThrows(IllegalArgumentException.class, () -> simCal.div(9, 0));

}

}


以下は実行例です。下記のように実行結果が表示されます。

@Nested

ネストしたテストクラスを作成でき、実施するテストをグループ化できます。

import org.junit.jupiter.api.DisplayName;

import org.junit.jupiter.api.Nested;

import org.junit.jupiter.api.Test;


@Nested

@DisplayName("クラス1")

class SimpleCalculatorTest extends SimpleCalculator {

@Test

@DisplayName("テストケース1-1-1")

void testDivException01() {

// オブジェクト生成

SimpleCalculator simCal = new SimpleCalculator();

// ラムダ式で、0で除算する。

assertThrows(IllegalArgumentException.class, () -> simCal.div(9, 0));

}

@Test

@DisplayName("テストケース1-1-2")

void testDivException02() {

// オブジェクト生成

SimpleCalculator simCal = new SimpleCalculator();

// ラムダ式で、0で除算する。

assertThrows(IllegalArgumentException.class, () -> simCal.div(9, 0));

}

}


@Nested

@DisplayName("クラス2")

class SimpleTest02 extends SimpleCalculator {

@Test

@DisplayName("テストケース1-1-3")

void testDivException03() {

// オブジェクト生成

SimpleCalculator simCal = new SimpleCalculator();

// ラムダ式で、0で除算する。

assertThrows(IllegalArgumentException.class, () -> simCal.div(9, 0));

}

@Test

@DisplayName("テストケース1-1-4")

void testDivException04() {

// オブジェクト生成

SimpleCalculator simCal = new SimpleCalculator();

// ラムダ式で、0で除算する。

assertThrows(IllegalArgumentException.class, () -> simCal.div(9, 0));

}

}

JUnitを起動しようとすると、下記のような選択画面が表示され、@Nestedされた単位でのテストを実施できるようになります。

@Tag

クラスやメソッドにタグ付けをすることができ、フィルタリングすることができる。
ただし、EclipseなどのIDEから実行する際は特に変化はない。

使い方は下記のように@Tagをつけるだけですが、調べたところGradleなどのプラットフォーム上でフィルタリング等できるみたいです。

@Test

@Tag("タグ1のテスト")

void testDivException01() {

System.out.println("タグ1の処理です。");

}


@Test

@Tag("タグ2のテスト")

void testDivException02() {

System.out.println("タグ2の処理です。");

}


@BeforeEach

各テストメソッドを実行される前に呼ばれるもので、最初に共通で呼びたい処理などを書くことでテストの可読性を高めます。
例えば、以下のようなJUnitを実行したとします。

@BeforeEach

public void init() {

System.out.println("@BeforeEachの処理は、最初に呼ばれます。");

}


@Test

void testDivException01() {

System.out.println("タグ1の処理です。");

}


@Test

void testDivException02() {

System.out.println("タグ2の処理です。");

}


下記のように、各テストメソッドが呼ばれる前に@BeforeEachのメソッドが呼ばれます。


@ParameterizedTest

@Testの代わりに置くことで、
パラメータ化テスト(複数のテストデータで、同じテストメソッドを繰り返し実行するテスト)をできる。

データを設定する方法として、
下記の「@CsvSource」と「@ValueSource」を使う方法がある。

@CsvSource

単一のデータの型と値を設定して順次実行できる。

@ParameterizedTest

@ValueSource(ints = {1, 2, 3, 4, 5})

void test(int value) {

System.out.println(value);

}


ちなみにデータ型は、int型以外にも設定できるみたいです。

実行結果は下記になります。下記のように順次実行されます。


@ValueSource

カンマ区切りの値を使用してテストデータを設定して順次実行します。

@ParameterizedTest

@CsvSource({ "John, 25", "Jane, 30", "Tom, 35" })

void test(String name, int age) {

System.out.println(name + "は"+ age + "歳です。");

}


実行結果は下記になります。下記のように順次実行されます。