[[HOME>http://www.trance.co.jp/]] > [[技術情報]] > [[Java>http://www.trance.co.jp/wiki/index.php?%B5%BB%BD%D1%BE%F0%CA%F3#xe479566]] > JUnit4 * JUnit4 [#c858077d] #contents ** JUnitとは? [#na72a417] Java用の単体テストフレームワーク。 JUnitのようなテスティングフレームワークを活用することで、次のメリットがある。 + テストを統一な方法で作成できる → 他人が見ても分かりやすい + テストが簡単にできる また、単体テストコードがあれば、仕様変更時のデグレードを早い段階で発見することができる。 ** JUnit4の特徴は? [#s7d096f9] J2SE5。0のアノテーションを取り入れ、テスト記述方法のルールがシンプルになった。 J2SE5.0のアノテーションを取り入れ、テスト記述方法のルールがシンプルになった。 ** JUnit3との違いは? [#ideba8e3] -「junit.framework.TestCase」クラスを継承しなくてもよい。 - テストメソッドのプレフィックスに「test」の必要がない。 - テストクラス前後に行う処理を指定できるようになった。(@BeforeClass、@AfterClass) - 例外検証のソースの記述が簡単になった。(@Test(expected=XXXXException.class)) - パフォーマンスの検証もできるようになった。(@Test(timeout=1500)) - テストを無視することができるようになった。(@Ignore("実行しない理由を書く")) ** 記述方法の違いは? [#v86aab5d] *** テストクラス [#j0cb2422] - JUnit3 import junit.framework.TestCase; public class SampleTest extends TestCase { } - JUnit4 「junit.framework.TestCase」を継承しないくてもよい。 import static org.junit.Assert.*; public class SampleTest { } *** 通常テストメソッド [#y0103bba] - JUnit3 public void testFoo() { } - JUnit4 「@Test」を記述する。 テストメソッド名のプレフィックスに「test」が要らない。 @Test public void foo() { } *** 例外検証テストメソッド [#c73bca93] - JUnit3 public void testException() { String string = null; try { fail(); } catch (NullPointerException expected) { assertTrue(true); } } - JUnit4 「@Test」の「expected」要素に期待する例外クラスを名を記述する。 @Test(expected=NullPointerException.class) public void exception() { String string = null; string。toUpperCase(); } *** テストメソッドの前処理 [#v08a0341] - JUnit3 public void setUp() { // 前処理 } - JUnit4 「@Before」を記述する。 メソッド名は任意。 @Before public void before() { // 前処理 } *** テストメソッドの後処理 [#q4949f72] - JUnit3 public void tearDown() { // 後処理 } - JUnit4 「@After」を記述する。 メソッド名は任意。 @After public void after() { // 後処理 } ** 新しい機能は? [#k8ab9b07] *** パフォーマンス検証テストメソッド [#d66b67ab] 「@Test」の「timeout」要素に実行時間を記述する(ms)。 // 1500ms以下であること。 @Test(timeout=1500) public void time() throws InterruptedException { Thread。sleep(1000); } *** テストを無視する [#f69b853b] 「@Ignore」を記述する。 @Ignore("実行しない理由を記述する") @Test public void foo() { String string = "無視する"; assertEquals("無視する", string); } *** オブジェクト型配列の検証 [#p6079452] assertEquals(Object[] array1, Object[] array2); assertEquals(String message, Object[] array1, Object[] array2); *** テストクラスの前処理 [#d5e063f3] 「@BeforeClass」を記述する。 テストクラス実行前に一度だけ実行される。 @BeforeClass public void beforClass() { // 前処理 } *** テストクラスの後処理 [#n8ff9cee] 「@AfterClass」を記述する。 テストクラス実行後に一度だけ実行される。 @AfterClass public void afterClass() { // 後処理 } *** パラメータの指定 [#o9583d5f] テストクラスに「@RunWith(Parameterized.class)」を記述する。 パラメータ指定に「@Parameters」を記述する。 テスト対象値をパラメータで指定することで、テストコードの増大を防ぐことができる。 - ソース import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class CalculatorTest { private int x; private int y; private int expected; // パラメータ指定した値がコンストラクタの引数に渡される. public CalculatorTest(int x, int y, int expected) { this.x = x; this.y = y; this.expected = expected; } // パラメータ指定 // staticとする // コレクション型として返す. @Parameters public static List parameter() { List<Integer[]> list = new ArrayList<Integer[]>(); // ここで指定した値がインスタンス生成時の引数と指定渡される. list.add(new Integer[]{0, 0, 0}); list.add(new Integer[]{2, -1, 1}); list.add(new Integer[]{1, 1, 2}); return list; } @Test public void add() { System.out.println("addテストメソッド実行"); System.out.println("x=" + this.x); System.out.println("y=" + this.y); System.out.println("expected=" + this.expected); // 足し算をする. int actual = new Calculator().add(this.x, this.y); assertEquals(this.expected, actual); } } - 実行結果 パラメータ指定した数分だけ繰り返し実行される。 上記例では、パラメータを3つ指定したので、テストメソッドが3回実行されている。 addテストメソッド実行 x=0 y=0 expected=0 addテストメソッド実行 x=2 y=-1 expected=1 addテストメソッド実行 x=1 y=1 expected=2 *** パラメータの指定 - テストメソッドが複数ある場合 [#jd1a7ff8] 現状のパラメータ指定の場合、テストメソッド毎パラメータを指定することはできない。 また、テストメソッドが複数ある場合の実行動作以下の通り。 - ソース import java.util.ArrayList; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class CalculatorTest { private int x; private int y; private int expected; public CalculatorTest(int x, int y, int expected) { this.x = x; this.y = y; this.expected = expected; } @Parameters public static List parameter() { List<Integer[]> list = new ArrayList<Integer[]>(); list.add(new Integer[]{0, 0, 0}); list.add(new Integer[]{2, -1, 1}); list.add(new Integer[]{1, 1, 2}); return list; } @Test public void add() { System.out.println("addテストメソッド実行"); System.out.println("x=" + this.x + " y=" + this.y + " expected=" + this.expected); } @Test public void subtract() { System.out.println("subtractテストメソッド実行"); System.out.println("x=" + this.x + " y=" + this.y + " expected=" + this.expected); } } - 実行結果 パラメータ指定回数分だけテストメソッドが実行される。 addテストメソッド実行 x=0 y=0 expected=0 subtractテストメソッド実行 x=0 y=0 expected=0 addテストメソッド実行 x=2 y=-1 expected=1 subtractテストメソッド実行 x=2 y=-1 expected=1 addテストメソッド実行 x=1 y=1 expected=2 subtractテストメソッド実行 x=1 y=1 expected=2 *** assertThat (Junit4.4〜) [#id5e481a] Junit4.4から新しいアサーションメソッド「assertThat」が追加された。 これまでのアサーションメソッドは、メソッド自体がアサーション条件であったが、「assertThat」では、引数にアサーション条件を指定する。 同値チェック 今まで // assertEquals(期待値, 実行値); assertEquals(3, 1 + 2); assertThatを使用 // assertThat(実行値, is(期待値)); assertThat(1 + 2, is(3)); assertThatアサーションメソッドを使用すると、正しいかの条件の指定(「assertThatメソッドの引数」)をより英語の文のような感じになる。 &color(red){注意事項}; 「import static」で以下のクラスをインポートすること。 上記サンプルの「is()」は、「org.hamcrest.CoreMatchers」クラスのスタティックメソッド。 // JMockのマッチングクラス import static org.hamcrest.CoreMatchers.*; // JUnitのマッチングクラス import static org.junit.matchers.JUnitMatchers.*; -メリット --コードの可読性が高くなる →「assertThat」の引数が英語の文章のようになるため(assertThat("A", is("A"))) --アサーションエラーメッセージが分かりいやすい --アサーション条件処理を独自に作成することが可能になる -assertThatの引数で使用する比較メソッド一覧 --org.hamcrest.CoreMatchers |~メソッド名|~用途| |allOf|指定した比較メソッドが全てtrueであるかチェック| |anyOf|指定した比較メソッドが1つでもtrueであるかチェック| |is|同値比較(equalToのショートカット)&br;assertThat(2, is(2));| |not|指定した値ではないチェック&br;assertThat(1, is(not(2)));| |equalTo|同値チェック&br;assertThat(2, equalTo(2));| |instanceOf|指定したクラスのインスタンスであるかチェック&br;assertThat(new ArrayList(), instanceOf(ArrayList.class));| |sameInstance|同じインスタンスであるかチェック&br;String same = "same";&br;assertThat(same, sameInstance(same));| |anything|| |any|| |nullValue|「null」チェック&br;assertThat(null, nullValue());| |notNullValue|not「null」チェック&br;assertThat("", notNullValue());| |describedAs|| --org.junit.matchers.JUnitMatchers |~メソッド名|~用途| |hasItem|指定した値を保持しているかチェック&br;assertThat(Arrays.asList(new String[]{"3"}), hasItem("3"));| |hasItems|指定した値を全て保持しているかチェック&br;assertThat(Arrays.asList(new String[]{"3", "4", "5"}), hasItems("3", "4"));| |containsString|指定した文字列を含んでいるかチェック&br;assertThat("test", containsString("t"));| |each|コレクションんが保持する値が全て指定した値であるかチェック&br;assertThat(Arrays.asList(new String[]{"3", "3"}), each(is("3")));| |both|指定した比較メソッドが全てtrueであるかチェック(and()メソッドを使用)&br;assertThat("test", both(containsString("t")).and(containsString("s")));| |either|指定した比較メソッドが1つでもtrueであるかチェック(or()メソッドを使用)&br;assertThat("test", either(containsString("t")).or(containsString("a")));| ** 実行順序 [#xe1e2407] - ソース public class SampleTest2 { static { System.out.println("クラス初期化"); } public SampleTest2() { System.out.println("コンストラクタ"); } @BeforeClass public static void setUpBeforeClass() throws Exception { System.out.println("@BeforeClass"); } @AfterClass public static void tearDownAfterClass() throws Exception { System.out.println("@AfterClass"); } @Before public void setUp() throws Exception { System.out.println("@Before"); } @After public void tearDown() throws Exception { System.out.println("@After"); } @Test public void test() { System.out.println("テストメソッド"); } } - 結果 クラス初期化 @BeforeClass コンストラクタ @Before テストメソッド @After @AfterClass ** アノテーション一覧 [#la873a28] LEFT: |~アノテーション|~意味| |@Test|テスト対象のメソッドに記述する。&br;exception:例外テストの際、例外クラス名を記述する。&br;timeout:パフォーマンス検証テストの際、実行時間をミリ秒で記述する。| |@Before|テストメソッドの前処理のメソッドに記述する。| |@After|テストメソッドの後処理のメソッドに記述する。| |@BeforeClass|テストクラスの前処理のメソッドに記述する。| |@AfterClass|テストクラスの後処理のメソッドに記述する。| |@Ignore|テスト対象外にするメソッドに記述する(テストを実行しない場合に記述する)。| |@Parameters|テストで使用するパラメータを生成するメソッドに記述する。| |@RunWith|@Parametersで定義したパラメータを使用する等のテストランナを記述する。| ** Eclipse関連 [#rdb6bfcd] *** サポートしているEclipseのバージョンは? [#zc793c64] Eclipse3.2〜 *** EclipseでJUnit4を使用するには? [#ha2b7972] + [File] -> [New] -> [JUnit Test Case]を選択する。 + 一番上のラジオボタンで「New JUnit 4 test」を指定する。 *** 便利なプラグイン [#e725177f] - Quick JUnit Plugin for Eclipse &color(red){※注意}; --2007/04/19 JUnitテスト起動ショートカットキー[Ctrl + 0]を実行しても、「JUnit テストケースを選択してください。」のメッセージが表示されてしまい、実行されない。 --2007/04/26 最新版では、上記問題が解決された。 まだ、「@Parameters」を使用するテストはうまくいかない(途中で止まる)。 - djunit