JUnitクラスの構造

public class XXXTest extends TestCase{
 
 // コンストラクタ
 public XXXTest(String arg0){
   super(arg0);
 }
 
 // テストメソッド
 // testで始まるメソッド
 public void testAAAA(){
   //テストの内容
   //  テスト対象のメソッドを実行して
   //  assertXXXX()メソッドで結果を検証
 }
 
 // 各テストメソッドの初期化処理
 public void setUp(){
 }
 
 // 各テストメソッドの終了処理
 public static void tearDown(){
 }
 
 // このテストクラスの初期化処理
 public static void oneTimeSetUp(){
 }
 
 // このテストクラスの終了処理
 public void oneTimeTearDown(){
 }
 
 // JUnitは、suite()の返り値のTestを実行する
 // ontTimeSetup() / oneTimeTearDown() を実装する為に
 // suite()をオーバーライドして、XXXTest.class->TestSuit->TestSetup
 // でwrapしたものを返す。
 public static Test suite() throws Exception {
   TestSuite suite = new TestSuite(XXXTest.class);
   TestSetup wrapper = new TestSetup(suite) {
     public void setUp() throws Exception {
       oneTimeSetUp();
     }
     public void tearDown() throws Excepiton {
       oneTimeTearDown();
     }
   };
   return wrapper;
 }
}
  1. テストクラスの名前は、XXXTest にする。バッチテスト?で**Test.javaをテストクラスと見なして全実行するため。
  2. テストメソッドはtestで始まるテストクラス
    1. 各テストメソッドの初期化処理はsetUp()に記述する
    2. 各テストメソッドの終了処理はtearDown()に記述する
    3. 基本的にtestXXX()内で、処理を行い、assertXXXX()メソッドで結果の検証をする
  3. JUnit.assertXXXX()メソッドは、期待した結果が得られない場合、AssertionFailedException?が発生する。JUnitフレームワークは何らかのExceptionを受け取るとテストに失敗したものと見なす。
  4. JUnit(Test Runner)は、suite()から返されるテストを実行する
    1. 通常(TestCase?#suite())はテストケース自身が返される
    2. テストクラス全体の初期化/終了処理をするときには、suite()をオーバーライドして、TestCase?->TestSuite?->TestSetup?の順でwrapしたものを返す。
    3. テストメソッドの実行順序を指定したい時には、以下のように、テストケースのコンストラクタの引数にテストメソッド名を与えてインスタンス化し、TestSuite?に追加する
       public static Test suite() throws Exception {
         TestSuite suite = new TestSuite("XXXクラスのテスト");
         suite.addTest( new TestSuite(new XXXTest("testFirst") ) );
         suite.addTest( new TestSuite(new XXXTest("testSecond") ) );
         suite.addTest( new TestSuite(new XXXTest("testThird") ) );
         suite.addTest( new TestSuite(new XXXTest("testEnd") ) );
         TestSetup wrapper = new TestSetup(suite) {
           public void setUp() throws Exception {
             oneTimeSetup();
           }
           public void tearDown() throws Excepiton {
             ontTimeTearDown();
           }
         };
         return wrapper;
       }
      このとき、各テストメソッド間で持ち回る値を格納したXXXTestクラスのフィールドはstaticにしなければならない事に注意。
      起動される各テストメソッドはそれぞれ別のインスタンスのXXXTestクラスのメソッドだから

assertEquals

assertEqualsは内容が同じかどうかをテストするメソッド

  1. assertEquals(プリミティブ型 expected, プリミティブ型 actual)
  2. assertEquals(Object expected, Object actual)
  3. assertEquals(String expected, String actual)
  4. assertEquals(String message, プリミティブ型 expected, プリミティブ型 actual)
  5. assertEquals(String message, Object expected, Object actual)
  6. assertEquals(String message, String expected, String actual)
  7. assertEquals(double 期待値, double 実測値, double 許容誤差)

DTOのassertEquals

DTO*1AssertEquals?をする時には、toString() メソッドで文字列にできるようにしておくと良い

JUnit:
 assertEquals( expectedDTO.toString(), actualDTO.toString() )

DTO:
 public class DTO implements Serializable{
   private String foo;
   private float bar;
   
   public String toString(){
     StringBuffer sbuf = new StringBuffer();
     sbuf.append( "foo=" + foo + ",");
     sbuf.append( "bar=" + bar );
     return sbuf.toString();
   }
}

MapのassertEquals

key値を辞書順に並べてString型に変換する。以下のメソッドをTestクラスの上位クラスにするなり、ユーティリティクラスをを作成して実装する。
Mapを拡張したDTOをつくるのは・・・やめた方が良い(ツブシが効かないシステムになる)。

public String mapToString( map ){
  ArrayList keys = new ArrayList( map.keySet() );
  Collections.sort( keys );

  StringBuffer sbuf = new StringBuffer();
  for( Iterator it = keys.iterator() ; it.hasNext() ; ){
    Object key = it.next();
    sbuf.append( key );
    sbuf.append( "=" );
    
    Object val = map.get( key );
    if( val instanceof Map ){
      sbuf.append( "{" + mapToString((Map)val) + "}" );
    }else
      sbuf.append( val );
    }
    sbuf.append( "," );
  }
  return sbuf.substring( 0 , sbuf.length()-1 ); // 最後の","を除く
}

assertSame/NotSame?

assertSame/NotSame?は参照が同じか/違うかどうかをテストするメソッド

  1. assertSame(Object expected, Object actual)
  2. assertSame(String message, Object expected, Object actual)
  3. assertNotSame?(Object expected, Object actual)
  4. assertNotSame?(String message, Object expected, Object actual)

assertTrue/False

assertTrue/Falseは、結果がtrueか/falseかをテストするメソッド

  1. assertTrue(boolean condition)
  2. assertTrue(String message, boolean condition)
  3. assertFalse(boolean condition)
  4. assertFalse(String message, boolean condition)

assertNull/NotNull?

assertNull/NotNull?は、結果がNullか/Nullでないかをテストするメソッド

  1. assertNull(Object object)
  2. assertNull(String message, Object object)
  3. assertNotNull?(Object object)
  4. assertNotNull?(String message, Object object)

fail

failは、無条件にテストを失敗させるメソッド

  1. fail()
  2. fail(String message)

例外が発生したらテスト合格と見なしたい

void test(){
  try{
    Subject sbj = new Subject();
    sbj.setParameter( invalidParameter );
    sbj.doSomething()                          // ここで例外発生を期待
    fail("SomeExceptionが発生しませんでした"); // 例外が発生していない
  }catch( SomeException ex ){
    ex=null;                    // SomeExceptionが発生したらテスト合格
  }
  ...(次の検証)...
}

JUnitとEcelipseとの連携

  1. Antの実行クラスパスにjunit.jarを加える
    [ウィンドウ]→[設定]→[Ant]→[ランタイム]→[グローバル項目]
    に、C:\eclipse\pligins\org.junit_3.8.1\junit.jar を加える
  2. Junit Test Caseの生成
    テスト対象のクラスを右クリックして
    [新規]-[JUnit テスト・ケース]
  3. Junit Test Caseの実行
    テストクラスを選択して、
    [実行]-[次を実行]-[3.Junitテスト]

テストメソッドに起動順序がある場合の雛形(コピペしてXXXXを置換してください)

import junit.extensions.TestSetup;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * XXXXのテスト.
 * <pre>
 * 1)します
 * 2)します
 * 3)します
 * 4)します
 * </pre>
 * @author
 * @version $Id$
 */
public class XXXXTest
 extends TestCase {
 /** テスト名 */
 private static final String TEST_NAME = XXXXTest.class.getName();

 /** メソッド名を起動する順に列挙 */
 private static final String[] METHODS = {"test1", "test2", "test3"};

 /**
  * コンストラクタ.
  *
  * @param arg0 メソッド名
  */
 public XXXXTest(final String arg0) {
   super(arg0);
 }
 
 /** テスト1. かならず最初に実行される */
 public void test1(){
 }
 
 /** テスト2. かならず、テスト1の後に実行される */
 public void test2(){
 }
 
 /** テスト3. かならず、テスト1,2の後に実行される */
 public void test3(){
 }
 
 /**
  *  このテストクラスの初期化処理
  */
 public static void oneTimeSetUp() {
 }

 /**
  * このテストクラスの終了処理
  */
 public static void oneTimeTearDown() {
 }

 /**
  * JUnitは、suite()の返り値のTestを実行する
  * ontTimeSetup() / oneTimeTearDown() を実装する為に
  * suite()をオーバーライドして、XXXTest.class->TestSuit->TestSetup
  * でwrapしたものを返す。
  *
  * @return TestSuite
  * @throws Exception 例外
  */
 public static Test suite() throws Exception {
   TestSuite suite = new TestSuite(TEST_NAME);

   for (int cnt = 0; cnt < METHODS.length; cnt++) {
     suite.addTest(new XXXXTest(METHODS[cnt]));
   }

   TestSetup wrapper =
     new TestSetup(suite) {
       public void setUp() throws Exception {
         oneTimeSetUp();
       }

       public void tearDown() throws Exception {
         oneTimeTearDown();
       }
     };

   return wrapper;
 }

 /**
  * 各テストメソッドの開始処理
  */
 public void setUp() {
 }

 /**
  * 各テストメソッドの終了処理
  */
 public void tearDown() {
 }
}

Java


*1 Data Transfer Object = モジュール間でデータを運ぶ為のJavaBeans

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   sitemap
Last-modified: 2006-02-18 (土) 13:08:01 (3940d)
ISBN10
ISBN13
9784061426061