HOME > 技術情報 > Java > JUnit4

JUnit4

JUnitとは?

Java用の単体テストフレームワーク。

JUnitのようなテスティングフレームワークを活用することで、次のメリットがある。

  1. テストを統一な方法で作成できる
    → 他人が見ても分かりやすい
  2. テストが簡単にできる

また、単体テストコードがあれば、仕様変更時のデグレードを早い段階で発見することができる。

JUnit4の特徴は?

J2SE5.0のアノテーションを取り入れ、テスト記述方法のルールがシンプルになった。

JUnit3との違いは?

  • 「junit.framework.TestCase」クラスを継承しなくてもよい。
  • テストメソッドのプレフィックスに「test」の必要がない。
  • テストクラス前後に行う処理を指定できるようになった。(@BeforeClass、@AfterClass)
  • 例外検証のソースの記述が簡単になった。(@Test(expected=XXXXException.class))
  • パフォーマンスの検証もできるようになった。(@Test(timeout=1500))
  • テストを無視することができるようになった。(@Ignore("実行しない理由を書く"))

記述方法の違いは?

テストクラス

  • JUnit3
    import junit.framework.TestCase;
    
    public class SampleTest extends TestCase {
    
    }
  • JUnit4
    「junit.framework.TestCase」を継承しないくてもよい。
    import static org.junit.Assert.*;
    
    public class SampleTest {
    
    }

通常テストメソッド

  • JUnit3
    public void testFoo() {
    
    }
  • JUnit4
    「@Test」を記述する。
    テストメソッド名のプレフィックスに「test」が要らない。
    @Test
    public void foo() {
    
    }

例外検証テストメソッド

  • 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();
    }

テストメソッドの前処理

  • JUnit3
    public void setUp() {
      // 前処理
    }
  • JUnit4
    「@Before」を記述する。
    メソッド名は任意。
    @Before
    public void before() {
      // 前処理
    }

テストメソッドの後処理

  • JUnit3
    public void tearDown() {
      // 後処理
    }
  • JUnit4
    「@After」を記述する。
    メソッド名は任意。
    @After
    public void after() {
      // 後処理
    }

新しい機能は?

パフォーマンス検証テストメソッド

「@Test」の「timeout」要素に実行時間を記述する(ms)。

// 1500ms以下であること。
@Test(timeout=1500)
public void time() throws InterruptedException {
  Thread。sleep(1000);
}

テストを無視する

「@Ignore」を記述する。

@Ignore("実行しない理由を記述する")
@Test
public void foo() {
  String string = "無視する";
  assertEquals("無視する", string);
}

オブジェクト型配列の検証

assertEquals(Object[] array1, Object[] array2);
assertEquals(String message, Object[] array1, Object[] array2);

テストクラスの前処理

「@BeforeClass」を記述する。
テストクラス実行前に一度だけ実行される。

@BeforeClass
public void beforClass() {
  // 前処理
}

テストクラスの後処理

「@AfterClass」を記述する。
テストクラス実行後に一度だけ実行される。

@AfterClass
public void afterClass() {
  // 後処理
}

パラメータの指定

テストクラスに「@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

パラメータの指定 - テストメソッドが複数ある場合

現状のパラメータ指定の場合、テストメソッド毎パラメータを指定することはできない。
また、テストメソッドが複数ある場合の実行動作以下の通り。

  • ソース
    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〜)

Junit4.4から新しいアサーションメソッド「assertThat」が追加された。
これまでのアサーションメソッドは、メソッド自体がアサーション条件であったが、「assertThat」では、引数にアサーション条件を指定する。

同値チェック
今まで

// assertEquals(期待値, 実行値);
assertEquals(3, 1 + 2);

assertThatを使用

// assertThat(実行値, is(期待値));
assertThat(1 + 2, is(3));

assertThatアサーションメソッドを使用すると、正しいかの条件の指定(「assertThatメソッドの引数」)をより英語の文のような感じになる。

注意事項
「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のショートカット)
      assertThat(2, is(2));
      not指定した値ではないチェック
      assertThat(1, is(not(2)));
      equalTo同値チェック
      assertThat(2, equalTo(2));
      instanceOf指定したクラスのインスタンスであるかチェック
      assertThat(new ArrayList(), instanceOf(ArrayList.class));
      sameInstance同じインスタンスであるかチェック
      String same = "same";
      assertThat(same, sameInstance(same));
      anything
      any
      nullValue「null」チェック
      assertThat(null, nullValue());
      notNullValuenot「null」チェック
      assertThat("", notNullValue());
      describedAs
    • org.junit.matchers.JUnitMatchers
      メソッド名用途
      hasItem指定した値を保持しているかチェック
      assertThat(Arrays.asList(new String[]{"3"}), hasItem("3"));
      hasItems指定した値を全て保持しているかチェック
      assertThat(Arrays.asList(new String[]{"3", "4", "5"}), hasItems("3", "4"));
      containsString指定した文字列を含んでいるかチェック
      assertThat("test", containsString("t"));
      eachコレクションんが保持する値が全て指定した値であるかチェック
      assertThat(Arrays.asList(new String[]{"3", "3"}), each(is("3")));
      both指定した比較メソッドが全てtrueであるかチェック(and()メソッドを使用)
      assertThat("test", both(containsString("t")).and(containsString("s")));
      either指定した比較メソッドが1つでもtrueであるかチェック(or()メソッドを使用)
      assertThat("test", either(containsString("t")).or(containsString("a")));

実行順序

  • ソース
    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

アノテーション一覧

アノテーション意味
@Testテスト対象のメソッドに記述する。
exception:例外テストの際、例外クラス名を記述する。
timeout:パフォーマンス検証テストの際、実行時間をミリ秒で記述する。
@Beforeテストメソッドの前処理のメソッドに記述する。
@Afterテストメソッドの後処理のメソッドに記述する。
@BeforeClassテストクラスの前処理のメソッドに記述する。
@AfterClassテストクラスの後処理のメソッドに記述する。
@Ignoreテスト対象外にするメソッドに記述する(テストを実行しない場合に記述する)。
@Parametersテストで使用するパラメータを生成するメソッドに記述する。
@RunWith@Parametersで定義したパラメータを使用する等のテストランナを記述する。

Eclipse関連

サポートしているEclipseのバージョンは?

Eclipse3.2〜

EclipseでJUnit4を使用するには?

  1. [File] -> [New] -> [JUnit Test Case]を選択する。
  2. 一番上のラジオボタンで「New JUnit 4 test」を指定する。

便利なプラグイン

  • Quick JUnit Plugin for Eclipse
    ※注意
    • 2007/04/19
      JUnitテスト起動ショートカットキー[Ctrl + 0]を実行しても、「JUnit テストケースを選択してください。」のメッセージが表示されてしまい、実行されない。
    • 2007/04/26
      最新版では、上記問題が解決された。
      まだ、「@Parameters」を使用するテストはうまくいかない(途中で止まる)。
  • djunit

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2007-08-15 (水) 16:15:00 (3512d)