サーチ…
備考
パラメータ | コンテキスト | 詳細 |
---|---|---|
@BeforeClass | 静的 | クラスが最初に作成されるときに実行されます。 |
@前 | インスタンス | クラスの各テストの前に実行されます。 |
@テスト | インスタンス | テストする各メソッドを宣言する必要があります。 |
@After | インスタンス | クラスの各テストの後に実行されます。 |
@放課後 | 静的 | クラスが破壊される前に実行される |
テストクラスのフォーマットの例
public class TestFeatureA {
@BeforeClass
public static void setupClass() {}
@Before
public void setupTest() {}
@Test
public void testA() {}
@Test
public void testB() {}
@After
public void tearDownTest() {}
@AfterClass
public static void tearDownClass() {}
}
}
JUnitを使用したユニットテスト
ここでは、クラスの持つCounter
メソッドとcountNumbers()
とhasNumbers()
public class Counter {
/* To count the numbers in the input */
public static int countNumbers(String input) {
int count = 0;
for (char letter : input.toCharArray()) {
if (Character.isDigit(letter))
count++;
}
return count;
}
/* To check whether the input has number*/
public static boolean hasNumber(String input) {
return input.matches(".*\\d.*");
}
}
このクラスを単体テストするには、Junitフレームワークを使用できます。プロジェクトクラスのパスにjunit.jar
を追加します。次に、以下のようにTest caseクラスを作成します。
import org.junit.Assert; // imports from the junit.jar
import org.junit.Test;
public class CounterTest {
@Test // Test annotation makes this method as a test case
public void countNumbersTest() {
int expectedCount = 3;
int actualCount = Counter.countNumbers("Hi 123");
Assert.assertEquals(expectedCount, actualCount); //compares expected and actual value
}
@Test
public void hasNumberTest() {
boolean expectedValue = false;
boolean actualValue = Counter.hasNumber("Hi there!");
Assert.assertEquals(expectedValue, actualValue);
}
}
あなたのIDEでは、このクラスを "Junit testcase"として実行し、GUIの出力を見ることができます。コマンドプロンプトで、次のようにテストケースをコンパイルして実行できます。
\> javac -cp ,;junit.jar CounterTest.java
\> java -cp .;junit.jar org.junit.runner.JUnitCore CounterTest
テストが正常に実行された結果は、次のようになります。
JUnit version 4.9b2
..
Time: 0.019
OK (2 tests)
テストが失敗した場合は、次のようになります。
Time: 0.024
There was 1 failure:
1) CountNumbersTest(CounterTest)
java.lang.AssertionError: expected:<30> but was:<3>
... // truncated output
FAILURES!!!
Tests run: 2, Failures: 1
備品
ウィキペディアから:
テストフィクスチャとは、アイテム、デバイス、またはソフトウェアの一部を一貫してテストするために使用されるものです。
また、テストメソッド自体から共通の初期化/終了コードを抽出することによって、テストの可読性を高めることもできます。
共通の初期化を各テストの前に実行するのではなく、1回実行できる場合、テストを実行するのにかかる時間も短縮できます。
以下の例は、JUnitによって提供される主なオプションを示すために考案されたものです。初期化に高価なクラスFoo
を仮定します。
public class Foo {
public Foo() {
// expensive initialization
}
public void cleanUp() {
// cleans up resources
}
}
別のクラスのBar
はFoo
への参照があります:
public class Bar {
private Foo foo;
public Bar(Foo foo) {
this.foo = foo;
}
public void cleanUp() {
// cleans up resources
}
}
以下のテストでは、単一のBar
を含むListの初期コンテキストを想定しています。
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class FixturesTest {
private static Foo referenceFoo;
private List<Bar> testContext;
@BeforeClass
public static void setupOnce() {
// Called once before any tests have run
referenceFoo = new Foo();
}
@Before
public void setup() {
// Called before each test is run
testContext = Arrays.asList(new Bar(referenceFoo));
}
@Test
public void testSingle() {
assertEquals("Wrong test context size", 1, testContext.size());
Bar baz = testContext.get(0);
assertEquals(referenceFoo, baz.getFoo());
}
@Test
public void testMultiple() {
testContext.add(new Bar(referenceFoo));
assertEquals("Wrong test context size", 2, testContext.size());
for (Bar baz : testContext) {
assertEquals(referenceFoo, baz.getFoo());
}
}
@After
public void tearDown() {
// Called after each test is run
for (Bar baz : testContext) {
baz.cleanUp();
}
}
@AfterClass
public void tearDownOnce() {
// Called once after all tests have run
referenceFoo.cleanUp();
}
}
この例では、 @BeforeClass
注釈付きのメソッドsetupOnce()
を使用してFoo
オブジェクトを作成していますが、これは初期化に高価です。いずれのテストでも変更されないことが重要です。そうでなければ、テスト実行の結果は個々のテストの実行順序に依存する可能性があります。各テストは独立しており、1つの小さな機能をテストするという考え方です。
@Before
注釈付きメソッドsetup()
は、テストコンテキストを設定します。コンテキストはテストの実行中に変更される可能性があります。そのため、各テストの前に初期化する必要があります。同等の効果は、この方法に含まれるコードを各試験方法の開始時に含めることによって達成することができた。
@After
注釈付きメソッドtearDown()
は、テストコンテキスト内のリソースをクリーンアップします。各テスト呼び出しの後に呼び出されるため、 @Before
注釈付きメソッドに割り当てられたリソースを解放するためによく使用されます。
@AfterClass
アノテートされたメソッドtearDownOnce()
は、すべてのテストが実行されるとリソースをクリーンアップします。このようなメソッドは、通常、初期化中に割り当てられたリソースを解放するため、または@BeforeClass
注釈付きメソッドで@BeforeClass
れます。つまり、テストが外部のテストクラスに依存しないように、単体テストでは外部リソースを避けるのが最善の方法です。
理論を用いたユニットテスト
JavaDocから
Theoriesランナーは、無限のデータセットのサブセットに対して特定の機能性をテストすることができます。
実行理論
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
@RunWith(Theories.class)
public class FixturesTest {
@Theory
public void theory(){
//...some asserts
}
}
@Theory
注釈を付けられたメソッドは、Theoriesランナーによって理論として読み込まれます。
@DataPointアノテーション
@RunWith(Theories.class)
public class FixturesTest {
@DataPoint
public static String dataPoint1 = "str1";
@DataPoint
public static String dataPoint2 = "str2";
@DataPoint
public static int intDataPoint = 2;
@Theory
public void theoryMethod(String dataPoint, int intData){
//...some asserts
}
}
@DataPoint
注釈が付けられた各フィールドは、理論の中の特定の型のメソッドパラメータとして使用されます。上記の例では、 theoryMethod
は、以下のパラメータで2回実行されます: ["str1", 2] , ["str2", 2]
@DataPointsアノテーション@RunWith(Theories.class)publicクラスFixturesTest {
@DataPoints
public static String[] dataPoints = new String[]{"str1", "str2"};
@DataPoints
public static int[] dataPoints = new int[]{1, 2};
@Theory
public void theoryMethod(String dataPoint, ){
//...some asserts
}
}
@DataPoints
注釈で注釈が付けられた配列の各要素は、理論の中の特定の型のメソッドパラメータとして使用されます。上記の例では、 theoryMethod
は["str1", 1], ["str2", 1], ["str1", 2], ["str2", 2]
パフォーマンス測定
テストメソッドが実行に時間がかかりすぎるかどうかを確認する必要がある場合は、@Testアノテーションのtimeoutプロパティを使用して、予想される実行時間を記述することで可能です。テストの実行にかかる時間(ミリ秒)が長くなると、テストメソッドが失敗します。
public class StringConcatenationTest {
private static final int TIMES = 10_000;
// timeout in milliseconds
@Test(timeout = 20)
public void testString(){
String res = "";
for (int i = 0; i < TIMES; i++) {
res += i;
}
System.out.println(res.length());
}
@Test(timeout = 20)
public void testStringBuilder(){
StringBuilder res = new StringBuilder();
for (int i = 0; i < TIMES; i++) {
res.append(i);
}
System.out.println(res.length());
}
@Test(timeout = 20)
public void testStringBuffer(){
StringBuffer res = new StringBufferr();
for (int i = 0; i < TIMES; i++) {
res.append(i);
}
System.out.println(res.length());
}
}
ほとんどの場合、 JVMウォーミングアップなしでtestString
は失敗します。しかし、 testStringBuffer
とtestStringBuilder
はこのテストに成功するはずです。