S-JIS[2007-09-11/2015-11-10] 変更履歴

JUnit4

JUnit4について。


概要

2007年時点で、JUnitのバージョンは3系と4系がある。4系はアノテーションを使うのでJDK1.5以上でないと使えない。
が、JUnitのクラスライブラリのインポートの仕方等が違うだけで、試験の記述方法はほとんど同じ。
Eclipse3.2なら どちらにも対応している。(Eclipse3.2のJUnit4はJUnit4.1っぽい)


JUnit3.8とJUnit4.1の相違

  JUnit3.8 JUnit4.1
ライブラリのインポート TestCaseクラスをインポートする。 Assertクラスの各メソッドをstaticインポートする。
Testアノテーション等をインポートする。
テストクラスの定義 TestCaseを継承する必要がある。 特になし。
テストメソッドの定義 public void test〜()
testで始まる名前で、public voidで引数なしのメソッドが実行対象。
@Test public void 〜()
@Testアノテーションを付けたpublic voidで引数なしのメソッドが実行対象。
テストメソッド実行前後 setUp()・tearDown()が各テストメソッドの実行前後に呼ばれる。 @Before・@Afterを付けたメソッドが、各テストメソッドの実行前後に呼ばれる。
全テストの実行前後 なし。 @BeforeClass・@AfterClassを付けたメソッドが、全テストの実行前後に呼ばれる。
等値の確認 TestCase#assertEquals()を使用。
TestCaseを継承しているので「assertEquals()」で使用可能)
TestCaseはAssertを継承しているのでAssert.assertEquals()でも呼べるけど、そんな面倒な事はしないわな(苦笑)
Assert.assertEquals()を使用。
static importすれば「assertEquals()」で使用可能)
例外発生の確認 Exceptionをcatchし、catchできなかったらfail()を呼ぶようコーディング。 @Testアノテーションの引数expectedに発生すべき例外クラスを指定。
実装例 JUnit3.8 JUnit4.1
import junit.framework.TestCase;
 
public class SampleTest extends TestCase {
 
public void testNormal() {
  対象クラス obj = new 対象クラス();
  int r = obj.試験対象メソッド();
  assertEquals(123, r);
  assertEquals(456, obj.get内部状態());
}
 
public void testException() {
  try {
     試験対象実行();
     fail("例外が発生するはず");
  } catch(発生すべき例外 e) {
     // success
     assertEquals("文言", e.getMessage());
  }

  //試験の続き〜
}
}
import static org.junit.Assert.*;
import org.junit.Test;
public class SampleTest {
@Test
public void normal() {
  対象クラス obj = new 対象クラス();
  int r = obj.試験対象メソッド();
  assertEquals(123, r);
  assertEquals(456, obj.get内部状態());
}
@Test(expected=発生すべき例外.class)
public void testException() {

  試験対象実行();



  //文言の確認は無理そう?


  //別の試験を続けるのは無理そう?
}
}

参考: 沖ソフトウェア株式会社のJUnit 4 & TestNG


テストの実行

EclipseでのJUnit実行方法


テストの実装

テストは、試験したい対象メソッドを呼び出し、戻り値(や呼び出し後の状態)が想定した結果になっているかどうかをチェックすることにより行う。
つまりプログラマーは、テスト対象メソッドの呼び出しと、正しいはずの値(戻り値のチェック)をコーディングする。

チェックについてはJUnitで用意されているテスト結果判定用メソッド(assertEquals()等のメソッド)を呼び出すことによって行う。
テスト結果判定用メソッドは、テストが成功した場合は正常に終了し、テストが失敗した場合に例外を発生させる。
例えばassertEquals()の場合、想定した値と実行結果が等しければ普通に戻り(すなわち試験成功)、等しくなければ例外が発生する(すなわち試験失敗)。

testから始まる(あるいは@Testを付けた)メソッドがテストを記述するメソッドとして扱われる。
これらのメソッドがJUnit実行時にJUnitフレームワークから呼ばれる。(実行順序は不定)

setUp()(あるいは@Beforeを付けたメソッド)は各テストメソッドの実行前に呼ばれるので、共通の準備作業が必要な場合にコーディングしておく。

テスト結果判定用メソッド
メソッド 説明 備考
assertEquals(型 expected, 型 actual) expected(期待値)とactual(実行結果)が等しい場合、テスト成功 「型」は、boolean・byte・char・short・int・long
assertEquals(Object expected, Object actual) expectedとactualが等しい場合、テスト成功 Object#equals()で判断している
assertEquals(double expected, double actual, double delta) expectedとactualの差(の絶対値)がdeltaより小さい場合、テスト成功
(浮動小数の場合、ぴったり一致するという判定は非常に怪しいからdeltaというものがあるのだろう)
float版もある
assertArrayEquals(配列 expected, 配列 actual) 配列の内容を比較する。[2009-12-02]  
assertNotNull(Object obj) objがnull以外の場合、テスト成功  
assertNull(Object obj) objがnullの場合、テスト成功  
assertSame(Object expected, Object actual) expected==actualの場合、テスト成功  
assertNotSame(Object expected, Object actual) expected!=actualの場合、テスト成功  
assertTrue(boolean cond) condがtrueの場合、テスト成功  
assertFalse(boolean cond) condがfalseの場合、テスト成功  
fail() 常にテスト失敗 「ここに来るはずがない」
「ここに来たら試験失敗」
という箇所に記述する

上記のメソッドには、“テスト失敗時のメッセージ出力用の「String message」”を第1引数に持つメソッドも用意されている。
Eclipseで実行した場合、テスト失敗時にこのメッセージが「障害トレース」に表示される。


同一テストを複数データで実行

JUnit4.4から、テストメソッドに引数を指定することで、複数のデータで同一テストを実行することが出来るようになったらしい。[2015-11-10]

この機能を使うためには、まず、テストクラスに「@RunWith(Theories.class)」を指定する。
そして、テストメソッドに「@Test」の代わりに「@Theory」を付け、引数を追加する。
引数に指定する値は、フィールドに「@DataPoint」を付けると、それが引数として使われる。フィールドを複数用意すると、それぞれの引数を使ってテストメソッドが実行される。
テストメソッドの引数と合致する型のDataPointフィールドが引数として使われる。

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.junit.experimental.theories.DataPoint;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
@RunWith(Theories.class)
public class TheoryTest {

	@DataPoint
	public static int VALUE0 = 0;

	@DataPoint
	public static int VALUE2 = 2;

	@Theory
	public void test(int value) {
		assertThat(value % 2, is(0));
	}
}

@DataPoint」の代わりに「@DataPoints」を使って配列を指定すると、複数のDataPointをまとめることが出来る。

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
@RunWith(Theories.class)
public class TheoryTest {

	@DataPoints
	public static int[] VALUES = { 0, 2, 4 };

	@Theory
	public void test(int value) {
		assertThat(value % 2, is(0));
	}
}

JUnitへ戻る / Java目次へ戻る / EclipseのJUnitへ行く / 新機能へ戻る / 技術メモへ戻る
メールの送信先:ひしだま