JUnit4 の実行順序
最近 JUnit にハマっています(笑)
アノテーションベースに生まれ変わった JUnit4
JUnit4 系では、アノテーションベースになり、テストがとても書きやすくなった(し、可読性も上がった)と個人的には感じている。
ただ、このアノテーション、結構な種類があり、どのアノテーションで定義されたものが、どのタイミングで実行されるのか、いまいち押さえられていない。ということで、今回はよく使われる @Before とか @After の他に、@RunWith、@Rule で指定できる TestWatcher の実行タイミングについても簡単に調べてみた。
テスト対象のクラス達
Runner
import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.InitializationError; public class DummyJUnit4ClassRunner extends BlockJUnit4ClassRunner { public DummyJUnit4ClassRunner(Class<?> clazz) throws InitializationError { super(clazz); System.out.println("DummyJUnit4ClassRunner"); } }
TestWatcher
import org.junit.rules.TestWatcher; import org.junit.runner.Description; public class DummyTestWacher extends TestWatcher { public DummyTestWacher() { System.out.println("DummyTestWacher"); } @Override protected void starting(Description description) { System.out.println("DummyTestWacher#starting"); } @Override protected void finished(Description description) { System.out.println("DummyTestWacher#finished"); } }
テストクラス
import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(DummyJUnit4ClassRunner.class) public class JUnitExecutionSequenceLearningTest { @Rule public DummyTestWacher wacher = new DummyTestWacher(); public JUnitExecutionSequenceLearningTest() { System.out.println("SubTest"); } @BeforeClass public static void beforeOnce() { System.out.println("@BeforeClass"); } @Before public void before() { System.out.println("@Before"); } @After public void after() { System.out.println("@After"); } @AfterClass public static void afterOnce() { System.out.println("@AfterClass"); } @Test public void test1() { System.out.println("@Test-1"); } @Test public void test2() { System.out.println("@Test-2"); } }
結果
で、これを実行した結果がコレ。
DummyJUnit4ClassRunner @BeforeClass DummyTestWacher SubTest DummyTestWacher#starting @Before @Test-1 @After DummyTestWacher#finished DummyTestWacher SubTest DummyTestWacher#starting @Before @Test-2 @After DummyTestWacher#finished @AfterClass
ランナーは何よりも先に呼び出されるのね。
あと、@BeforeClass はテスト対象のクラスがインスタンス化されるよりも前に呼び出されるんだ〜。
確かに @BeforeClass は、メソッドシグネチャも public static じゃないと怒られるからな。そりゃそうか。
あとは、まぁ何となく予想通りかな。
@Rule の可能性
このルールクラスは何となくやけど、可能性がありそう。この辺りは別途調べて結果を載せるぜよ( *`ω´)