watch a test

ググればたくさん情報は得られるが、とりあえずメモ。

junit でテストを書く際、今何のテストをしているのか……などのログを吐きたいことがある。例えば wasavi のテストで、何らかのミスがあって、WebDriverWait がタイムアウトするとする。タイムアウト自体は catch 節で受け取るので、そこで単に System.out.println(“timed out!”); すれば ant が保存するログに含まれる。が、どのテストで発生したかまではわからない。

そこで、テストケースで

@Test public void foo () {
System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName());
}

などと書けばログにテスト中のメソッド名が書かれるので判別する材料になる。しかしこれはすべてのテストケースに埋め込まなければならないので、とても煩雑だ。

さて junit4 には TestWatcher というものが用意されていて、テスト開始・終了、あるいは成功時・失敗時に任意の処理をはさむことができる。開始・終了というのは @Before と @After と被っているが、これらはあくまでテスト視点での開始・終了なのに対して、TestWatcher のそれはテストランナーから見た、「テストメソッド」の開始・終了であり、テストメソッドの素性などのメタな情報を利用することができる。


import org.junit.*;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

public class WasaviTest {
protected String logText;

@Rule public TestRule watcher = new TestWatcher() {
protected void starting (Description d) {
System.out.println("Testcase: " + d.getMethodName());
}
protected void failed (Throwable e, Description d) {
System.out.println(d.getMethodName() + " FAILED\n" + logText);
}
};

@After
public void tearDown () {
logText = driver.findElement(By.id("test-log")).getAttribute("value");
}
}

こんな感じで自前のテストの基底クラスに仕込んでおけば、これを継承した個々のテストでは何も考えることなく勝手にテストケースの名前が出力される。

くわしくは javadoc を見れば全部書いてある。

Leave a Reply

Your email address will not be published. Required fields are marked *