JUnitでパラメータ化テストを実施する
JUnitでパラメータ化テストの実施方法メモです。
JUnitでテスト対象のメソッドに対して、複数パターンの入力値を検証する方法として
パラメータ化テストを試してみました。
テスト対象クラス作成
下記の三角形クラスを使ってテストしてみます。
Triangle.java
public class Triangle { private final int a; private final int b; private final int c; public Triangle(int a, int b, int c) { this.a = a; this.b = b; this.c = c; } // ヘロンの公式で面積を求める。 // 簡単のため、面積は四捨五入してintで返す。 public int area() { if (a == 0 || b == 0 || c == 0) throw new ArithmeticException("zero side"); double s = (a + b + c) / 2.0; double area = Math.sqrt(s * (s - a) * (s - b) * (s - c)); return (int)Math.round(area); } }
テストクラス作成
Triangle.javaに対応するテストクラスとして、
TriangleTest.javaクラスを作成します。
主なポイント
@RunWith
テストランナーを指定するアノテーションです。
Enclosed
ネストしたテストクラスでテストする場合のテストランナーです。
Theories
パラメータ化テストの際に指定するテストランナーです。
@DataPoints
1つのフィールドで複数のパラメータを定義するアノテーションです。
@Theory
パラメータ化テストのテストメソッドに付与するアノテーションです。
@Rule
独自のテストランナーを定義するアノテーションです。
ExpectedException
例外を検証するためのルールです。
TriangleFixture
可読性を高める為にフィクスチャオブジェクトを定義します。
テストするパラメータを保持するオブジェクトとします。
テストコードはこんな感じになりました。
TriangleTest.java
import org.junit.Rule; import org.junit.experimental.runners.Enclosed; import org.junit.experimental.theories.DataPoints; import org.junit.experimental.theories.Theories; import org.junit.experimental.theories.Theory; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; @RunWith(Enclosed.class) public class TriangleTest { @RunWith(Theories.class) public static class 辺の長さ0なし { @DataPoints public static TriangleFixture[] TRI = { new TriangleFixture(3, 4, 5, 6), new TriangleFixture(4, 10, 12, 19), new TriangleFixture(3, 3, 3, 4) }; @Theory public void area(TriangleFixture f) throws Exception { Triangle t = new Triangle(f.a, f.b, f.c); assertThat(t.area(), is(f.expected)); } } @RunWith(Theories.class) public static class 辺の長さ0あり { @DataPoints public static TriangleFixture[] TRI = { new TriangleFixture(0, 4, 5, 6), new TriangleFixture(4, 0, 12, 19), new TriangleFixture(3, 3, 0, 4) }; @Rule public ExpectedException thrown = ExpectedException.none(); @Theory public void area(TriangleFixture f) throws Exception { thrown.expect(ArithmeticException.class); Triangle t = new Triangle(f.a, f.b, f.c); t.area(); } } static class TriangleFixture { int a; int b; int c; int expected; TriangleFixture(int a, int b, int c, int expected) { this.a = a; this.b = b; this.c = c; this.expected = expected; } } }