現在、「JUnitinaction」の本を読んでいます。この本で私は以下のテキストを見つけました:
JUnitは、各@Testメソッドを呼び出す前に、テストクラスの新しいインスタンスを作成します。これにより、テスト方法間の独立性が確保され、テストコードでの意図しない副作用が回避されます。各テストメソッドは新しいテストクラスインスタンスで実行されるため、テストメソッド間でインスタンス変数値を再利用することはできません。
今、私はこのアプローチにあまり意味がありません:
例えば:
public class CalculatorTest {
@Test
public void testAdd_1() {
Calculator calculator = new Calculator();
double result = calculator.add(1, 1);
assertEquals(2, result, 0);
}
@Test
public void testAdd_2() {
Calculator calculator = new Calculator();
double result = calculator.add(2, 2);
assertEquals(4, result, 0);
}
}
テストクラスCalculatorTestの場合、利点はありません。
では、別の例に注目しましょう。
public class OneTest {
static byte count;
public OneTest() {
count++;
}
@Test
public void test1() {
System.out.println(count);
}
@Test
public void test2() {
System.out.println(count);
}
}
テストクラスOneTestの場合、多くのテストメソッドに同じ変数カウントを使用する方法を見つけました...
それで、本で説明されているアプローチの本当の利点をどのように見るのですか?
本に記載されているアプローチの本当の利点をどのように見るのですか?
個別のインスタンスの目的は、利益のためではなく、前のテストの実行に影響を与えることなく、各テストを個別に実行する必要があるという契約を維持することです。テストごとに異なるインスタンスを使用する以外に、このコントラクトを保証する方法は他にありません。
たとえば、Springトランザクション管理では、デフォルトで、同じコントラクトを維持するために、テストによってデータベースに加えられたすべての変更をロールバックします。
したがって、テストで静的変数を使用することは、テストごとに1つのインスタンスの目的全体を無効にして、テストごとにクリーンな状態にすることをお勧めします。
テストメソッド間で状態をクリーンに保つことは、単体テストには役立ちますが、テスト間に依存関係を持つことがしばしば必要な機能テストの邪魔になります(たとえば、Seleniumを使用してWebページをテストする場合、テストの実行を気にしないことが便利です。ログインページのテストが失敗した場合の特定のページ)。
これが、私が TestNG を作成した主な理由の1つでした。これは、各メソッド間で新しいクラスをインスタンス化しないため、この決定を課す代わりに選択肢を提供します。
TestNGは、テストの依存関係、マルチスレッドテストもサポートし、グループの概念(「サーブレットテストのみを実行する」)およびその他の多くの機能を備えています。
可変クラスをテストする場合、各テストメソッドの開始時にテスト対象のオブジェクトを既知の状態にすることには大きな価値があるため、テストの実行順序は重要ではありません。これを実現する最も簡単な方法は、テストごとにそのクラスの新しいインスタンスを作成し、静的フィールドを回避することです。
電卓の例では、Calculator
クラスは不変であり、メソッド呼び出しの結果はパラメーターのみに依存しているように見えます。したがって、あるテストが別のテストに影響を与えるリスクはありません。
2番目の例の要点はよくわかりません。共有静的フィールドを使用する@Test
アノテーションが付けられたメソッドを作成しましたが、メソッドにはアサーションがなく、実際には何もテストしていません。
静的フィールドを使用したい場合、または実際にテスト対象のクラスの単一のインスタンスを保持して再利用したい場合は、そうすることは確かに可能ですが、テストを機能させ、互いに独立した状態を維持するには、より注意が必要になる傾向があります。