TestNGのテストクラスを作ってみよう
ここからは、TestNGを利用したテストを作成しましょう。まず、リスト1はテストの対象となるTargetクラスです。足し算をする単純なメソッドadd()と例外を発生させるメソッドthrowException()を定義します。
public class Target {
public int add(int a, int b) {
return a + b;
}
public void throwException() {
throw new RuntimeException("例外が発生しました");
}
}
リスト2はTargetクラスを検証するテストクラスです。
import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class TestNGSample {
private Target target;
public TestNGSample() {
System.out.println(
"★TestNGSampleのコンストラクタを呼び出した★");
}
@Test
public void verifyAdd1() {
System.out.println("★★★verifyAdd1()を呼び出した★★★");
int result = target.add(1, 2);
assertEquals(result, 3);
}
@Test
public void verifyAdd2() {
System.out.println("★★★verifyAdd2()を呼び出した★★★");
int result = target.add(3, 3);
assertEquals(result, 6);
}
@BeforeMethod
public void init() {
System.out.println("★★init()を呼び出した★★");
target = new Target();
}
@Test(expectedExceptions
= { java.lang.RuntimeException.class })
public void exceptionTest() {
System.out.println(
"★★★exceptionTest()を呼び出した★★★");
target.throwException();
}
}
このTestNGSampleがTestNGのテストクラスです。テストクラスは何らかのクラスを継承する必要はありません。テストクラスにはテストメソッドを3つ定義しました。verifyAdd1()とverifyAdd2()、exceptionTest()です。
TestNGではテストメソッドに@Testアノテーションを付けます。メソッド名はtestで始める必要はなく、任意の名前を付けられます。
注目はexceptionTest()メソッドです。テストとして例外が発生するかどうかを検証する場合、@Testの属性expectedExceptionsに発生する例外クラスを指定します。テストを実行したときに、指定した例外が発生すればテストは成功、発生しなければテストは失敗となります。JUnit 3の例外テストと比較しても、意図が明確でコード量も少なくなっています。
もう1つ、@BeforeMethodアノテーションを付けたinit()メソッドを定義しました。これはテストメソッドではありません。BeforeMethodという英語の意味どおり、テストメソッドを実行する前に呼び出したいメソッドには@BeforeMethodを付けます。JUnit 3のsetUp()メソッドと同じ働きです。テストメソッドと同様、任意のメソッド名を付けられます。
また、JUnit 3のtearDown()と同じことを実現する場合は@AfterMethodアノテーションを付けます。TestNGには@BeforeXXX、@AfterXXXというアノテーションがほかにもいくつかあります。それらについては、次回詳しく解説します。
このテストを実行すると、以下のように出力されます。テストメソッドの前にinit()メソッドを呼び出していることが分かります。
★TestNGSampleのコンストラクタを呼び出した★ ★★init()を呼び出した★★ ★★★verifyAdd2()を呼び出した★★★ ★★init()を呼び出した★★ ★★★exceptionTest()を呼び出した★★★ ★★init()を呼び出した★★ ★★★verifyAdd1()を呼び出した★★★
なお、テストの実行については、この記事の最後でEclipseプラグインの導入と併せて解説します。
じゃあ、アノテーションを使うJUnit 4との違いは?
では、同じアノテーションベースのテスティングフレームワークであるJUnit 4とTestNGのテストを比較してみましょう。先ほどのテストをJUnit 4で記述すると、以下のようになります。
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
public class JUnit4Sample {
public JUnit4Sample() {
System.out.println(
"★JUnit 4Sampleのコンストラクタを呼び出した★");
}
private Target target;
@Test
public void verifyAdd1() {
System.out.println("★★★verifyAdd1()を呼び出した★★★");
assertEquals(target.add(1, 2), 3);
}
@Test
public void verifyAdd2() {
System.out.println("★★★verifyAdd2()を呼び出した★★★");
assertEquals(target.add(3, 3), 6);
}
@Before
public void init() {
System.out.println("★★init()メソッドを呼び出した★★");
target = new Target();
}
@Test(expected = java.lang.RuntimeException.class)
public void exceptionTest() {
System.out.println(
"★★exceptionTest()メソッドを呼び出した★★");
target.throwException();
}
}
TestNGのテストクラスと非常に似ています。@BeforeMethodが@Beforeに、@TestのexpectedExceptions属性がexpected属性に名前が変わっている以外に違いはありません。役割も同じです。
ただし、同じ@TestでもJUnit 4とTestNGでは別のアノテーションクラスであることに注意してください(import文に注目してください)。
JUnit 4とTestNGのアノテーションが似ている理由は、JUnit 4がTestNGより後に開発されたため、TestNGに影響を受けているからです。逆に考えると、エンジニアがJUnit 4からより機能の多いTestNGへ移行することも容易であるといえます。さて、このテストを実行すると、以下のように出力されます(※注:実行する場合、JUnit公式サイトから配布アーカイブをダウンロードしてクラスパスに追加してください)。
★JUnit 4Sampleのコンストラクタを呼び出した★ ★★init()メソッドを呼び出した★★ ★★★verifyAdd1()を呼び出した★★★ ★JUnit 4Sampleのコンストラクタを呼び出した★ ★★init()メソッドを呼び出した★★ ★★★verifyAdd2()を呼び出した★★★ ★JUnit 4Sampleのコンストラクタを呼び出した★ ★★init()メソッドを呼び出した★★ ★★exceptionTest()メソッドを呼び出した★★
TestNGの出力結果と見比べてください。大きな違いが1点あります。
TestNGはコンストラクタを1回しか呼び出していませんが、JUnit 4では3回呼び出しています。JUnit 3の問題点でも説明したとおり、JUnitはテストメソッドに対してインスタンスを1つ生成します。これは、JUnit 4でもJUnit 3でも同様です。TestNGはインスタンスを1つしか作らず、テスト間で状態を共有します。
次ページでは、TestNGのEclipseプラグインのインストールについて説明し、次回についてお話します。
Copyright © ITmedia, Inc. All Rights Reserved.
