抽象ベースクラスがあり、これを単体テスト(TestNG 5.10)のベースとして使用します。このクラスでは、テスト用に環境全体を初期化し、データベースマッピングを設定します。この抽象クラスには、初期化を行う@BeforeClass
アノテーションを持つメソッドがあります。
次に、@Test
メソッドと@BeforeClass
メソッドがある特定のクラスでそのクラスを拡張します。これらのメソッドは、環境のクラス固有の初期化を行います(たとえば、いくつかのレコードをデータベースに入れます)。
@BeforeClass
アノテーション付きメソッドの特定の順序を強制するにはどうすればよいですか?拡張クラスのクラスの前に抽象基本クラスのクラスを実行する必要があります。
例:
abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@BeforeClass
doSpecificInitialization() {...}
@Test
doTests() {...}
}
予想される順序:
A.doInitialization
B.doSpecificInitialization
B.doTests
実際の注文:
B.doSpecificInitialization // <- crashes, as the base init is missing
(A.doInitialization // <---not executed
B.doTests) // <-/
abstract
クラスに_@BeforeClass
_を置かないでください。各サブクラスから呼び出します。
_abstract class A {
void doInitialization() {}
}
class B extends A {
@BeforeClass
void doSpecificInitialization() {
super.doInitialization();
}
@Test
void doTests() {}
}
_
TestNGには @BeforeClass(dependsOnMethods={"doInitialization"})
-試してみてください。
edit:以下の回答はJUnitに対するものですが、ここに残しておきますとにかく、それは役に立つかもしれないからです。
JUnit api :「スーパークラスの@BeforeClassメソッドは、現在のクラスの前に実行されます。」
これをテストしましたが、うまくいくようです。
ただし、@ Odysが以下で言及するように、JUnitには異なる名前の2つのメソッドが必要です親がシャドウイングされるためです。
public
を抽象クラスに追加し、TestNG(6.0.1)はdoTests
の前にdoInitialization()を実行しました。クラスAからpublic
を削除すると、TestNGはdoInitialization()
を実行しません。
public abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@Test
doTests() {...}
}
5.11であなたの例を試したところ、基本クラスの@BeforeClassが最初に呼び出されました。
Testng.xmlファイルを投稿できますか? AとBの両方を指定しているのに、Bだけが必要な場合があります。
Testng-usersメーリングリストでフォローアップしてください。問題を詳しく調べることができます。
-セドリック
私はちょうどこれを経て、これを達成するためのもう1つの方法を見つけました。抽象クラスの@BeforeClass
または@BeforeMethod
でalwaysRun
を使用するだけで、期待どおりに機能します。
public class AbstractTestClass {
@BeforeClass(alwaysRun = true)
public void generalBeforeClass() {
// do stuff
specificBeforeClass();
}
}
For JUnit:@fortegaが述べたように:JUnit apiによると:「スーパークラスの@BeforeClassメソッドは、現在のクラスの前に実行されます。」
ただし、注意してください両方のメソッドに同じ名前を付けない。この場合、親メソッドは子親によって非表示になるためです。 ソース 。
実行時:JUnitCore.runClasses(TestClass.class);子の前に親を適切に実行します(super.SetUpBeforeClass();) Eclipseから実行する場合:何らかの理由で、基本クラスの実行に失敗します。回避策:基本クラスを明示的に呼び出します:(BaseTest.setUpBeforeClass();)アプリケーションから実行する場合は、基本クラスにフラグを付けて、それを確認しますすでにセットアップされているかどうか。したがって、両方の可能な方法(個人テスト用のEclipseから、ビルドリリース用のANTなど)で実行した場合、1回だけ実行されます。
これはEclipseのバグ、または少なくとも予期しない結果のようです。
インポート文を確認してください。そのはず
import org.testng.annotations.BeforeClass;
じゃない
import org.junit.BeforeClass;
dependsOnMethod
を使用できます。
例えば春の場合(AbstractTestNGSpringContextTests
)
@BeforeClass(alwaysRun = true, dependsOnMethods = "springTestContextPrepareTestInstance")
@BeforeClassメソッドに、空のspecificBeforeClass()メソッドを呼び出させてください。このメソッドは、次のようなサブクラスによって上書きされる場合とされない場合があります。
public class AbstractTestClass {
@BeforeClass
public void generalBeforeClass() {
// do stuff
specificBeforeClass();
}
protected void specificBeforeClass() {}
}
public class SpecificTest {
@Override
protected void specificBeforeClass() {
// Do specific stuff
}
// Tests
}
これは私のために働く-
abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@Override
@BeforeClass
doInitialization() {
//do class specific init
}
@Test
doTests() {...}
}
ここには別の簡単な解決策があります。
私の特定の状況は、スーパークラスの「BeforeClass」が実行される前に、サブクラスの「BeforeClass」から模擬サービスを注入する必要があるということです。
これを行うには、サブクラスで@ClassRule
を使用します。
例えば:
@ClassRule
public static ExternalResource mocksInjector = new ExternalResource() {
@Override
protected void before() {
// inject my mock services here
// Note: this is executed before the parent class @BeforeClass
}
};
これがお役に立てば幸いです。これにより、「逆」の順序で静的セットアップを効果的に実行できます。
スーパークラスのBeforeClassアノテーション付きメソッドから呼び出される、スーパークラスで抽象メソッドdoSpecialInit()を作成してみませんか。
したがって、クラスを継承する開発者は、このメソッドを実装する必要があります。
今日、似たような問題に直面しましたが、唯一の違いは基本クラスが抽象的ではなかったことです
これが私のケースです
public class A {
@BeforeClass
private void doInitialization() {...}
}
public class B extends A {
@BeforeClass
private void doSpecificInitialization() {...}
@Test
public void doTests() {...}
}
@BeforeClass
クラスAのメソッドは実行されませんでした。
プライバシー修飾子で遊んでいると、TestNG 実行しない a @BeforeClass
継承クラスからの注釈付きメソッドメソッドがクラス継承から見えない場合
したがって、これは動作します:
public class A {
@BeforeClass
private void doInitialization() {...}
}
public class B extends A {
@BeforeClass
//Here a privacy modifier matters -> please make sure your method is public or protected so it will be visible for ancestors
protected void doSpecificInitialization() {...}
@Test
public void doTests() {...}
}
その結果、次のことが起こります。