• このエントリーをはてなブックマークに追加

スポンサードリンク

はじめに

JUnit で, 結合テスト (Integration test), シナリオテストを書きたい.

トランザクションごとに長いテストを書く必要がある.

複数のトランザクションを順に処理していったときに, オブジェクトの状態の変化を検証したい.

JUnit はテストケースが独立

はじめ, トランザクションごとにテストケースを書いていたが, うまく動かない.. オブジェクトの状態が初期化されてしまう.

これは, JUnit の設計思想だった.

つまり, 各テストケースは独立だということ. テストで使用するオブジェクトはテストケース内で生成されて, テストケース内で消滅する.

たとえば

たとえば, このテストは失敗する. number は 0 が入っている.

import static org.junit.Assert.*;

import org.junit.Test;

public class MemoryTest {
	
	static int number;

	@Test
	public void test () {
		number = 1;
	}

	@Test
	public void test2 () {
		assertEquals (1, number);
	}
}

static を利用する

テスト間で状態を引き継ぐためには, 変数に static 修飾子をつける.

こうすると, 各テストケースの独立を破ることができる.

package test;

import static org.junit.Assert.*;

import org.junit.Test;

public class MemoryTest {
	
	static int number;
	static Foo foo;
	static Foo bar;	
	static Foo pee;		

	@Test
	public void test () {
		number = 1;
		foo = new Foo (1);
		bar = new Foo (foo);
		pee = new Foo ();		
	}

	@Test
	public void test2 () {
		assertEquals (1, number);
		assertEquals (1, foo.i);
		assertEquals (1, bar.foo.i);		
		assertEquals (2, pee.foo.i);
		foo.plus (3);
	}
	
	@Test
	public void test3 () {
		assertEquals (4, foo.i);
	}
	
}

class Foo {
	public int i;
	public Foo foo;
	
	public Foo (int i) {
		this.i = i;
	}
	
	public Foo () {
		this.foo = new Foo (2);
	}
	
	public Foo (Foo foo) {
		this.foo = foo;
	}
	
	public void plus (int i){
		this.i += i;
	}
}

テストの実行順序を制御する

JUnit のテストが実行される順番はランダム.

これだと, ステートフルなテストには不向きだ.

テストの実行順序を指定するには, 以下の方法がある

  • @FixMethodOrder (MethodSorters.NAME_ASCENDING) をクラスの頭に設定
  • メソッド名を 実行したいものから abc 順に変更.
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.junit.FixMethodOrder;

@FixMethodOrder (MethodSorters.NAME_ASCENDING)
public class MemoryTest {
	
	static int number;
	static Foo foo;
	static Foo bar;	
	static Foo pee;		

	@Test
	public void test () {
		number = 1;
		foo = new Foo (1);
		bar = new Foo (foo);
		pee = new Foo ();		
	}

	@Test
	public void test2 () {
		assertEquals (1, number);
		assertEquals (1, foo.i);
		assertEquals (1, bar.foo.i);		
		assertEquals (2, pee.foo.i);
		foo.plus (3);
	}
	
	@Test
	public void test3 () {
		assertEquals (4, foo.i);
	}
	
}