96

単体テスト (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)                // <-/
4

16 に答える 16

119

編集:以下の回答はJUnit用ですが、役立つ可能性があるため、とにかくここに残します。

JUnit apiによると、「スーパークラスの @BeforeClass メソッドは、現在のクラスの前に実行されます。」

これをテストしましたが、うまくいくようです。

ただし、@Odys が以下で言及しているように、JUnit の場合、2 つのメソッドに異なる名前を付ける必要がありますが、そうしないと、親がシャドウされるため、サブクラス メソッドのみが実行されます。

于 2010-01-25T14:28:35.880 に答える
53

クラス@BeforeClassに乗らないでください。abstract各サブクラスから呼び出します。

abstract class A {
    void doInitialization() {}
}

class B extends A {
    @BeforeClass
    void doSpecificInitialization() {
        super.doInitialization();
    }

    @Test
    void doTests() {}
}

TestNGが持っているよう@BeforeClass(dependsOnMethods={"doInitialization"})です-試してみてください。

于 2010-01-25T14:19:36.987 に答える
7

抽象クラスに追加publicし、TestNG (6.0.1) が doInitialization() の前に実行しましたdoTests。クラス A からdoInitialization()削除すると、TestNG が実行されません。public

public abstract class A {
 @BeforeClass
 doInitialization() {...}
}

class B extends A {    
 @Test
 doTests() {...}
}
于 2011-03-31T19:16:07.873 に答える
6

5.11 であなたの例を試してみたところ、最初に呼び出された基本クラスの @BeforeClass を取得しました。

testng.xml ファイルを投稿できますか? A と B の両方を指定しているのに、B だけが必要な場合があります。

お気軽に testng-users メーリング リストをフォローアップしてください。あなたの問題を詳しく調べることができます。

-- セドリック

于 2010-01-26T00:16:15.177 に答える
4

私はこれを経験し、これを達成するためのもう1つの方法を見つけました。alwaysRun抽象クラス上@BeforeClassまたは抽象クラス内で使用するだけ@BeforeMethodで、期待どおりに機能します。

public class AbstractTestClass {
    @BeforeClass(alwaysRun = true)
    public void generalBeforeClass() {
        // do stuff
        specificBeforeClass();
    }
}
于 2013-12-04T08:33:21.853 に答える
3

JUnitの場合:@fortegaが述べたように:JUnit APIによると:「スーパークラスの@BeforeClassメソッドは、現在のクラスの前に実行されます。」

ただし、両方のメソッドに同じ名前を付けないように注意してください。この場合、親メソッドは子親によって隠されます。ソース

于 2016-08-04T12:43:42.513 に答える
2

私が実行したとき: JUnitCore.runClasses(TestClass.class); 子の前に親を適切に実行します( super.SetUpBeforeClass(); は必要ありません) Eclipse から実行する場合: 何らかの理由で基本クラスの実行に失敗します。回避策: 基本クラスを明示的に呼び出します: ( BaseTest.setUpBeforeClass(); ) アプリケーションから実行する場合に備えて、既にセットアップされているかどうかを判断するために、基本クラスにフラグが必要な場合があります。したがって、両方の可能な方法 (個人的なテスト用の Eclipse から、ビルド リリース用の ANT など) を介して実行した場合、1 回だけ実行されます。

これは Eclipse のバグか、少なくとも予期しない結果のようです。

于 2011-11-17T20:56:14.593 に答える
1

@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
}
于 2010-07-09T11:41:22.007 に答える
1

dependsOnMethodに使える。

例)Springの場合(AbstractTestNGSpringContextTests

@BeforeClass(alwaysRun = true, dependsOnMethods = "springTestContextPrepareTestInstance")
于 2015-07-21T18:23:18.460 に答える
0

スーパークラスの BeforeClass アノテーション付きメソッドから呼び出される抽象メソッド doSpecialInit() をスーパークラスに作成してみませんか。

したがって、クラスを継承する開発者は、このメソッドを実装する必要があります。

于 2013-09-04T14:34:50.370 に答える
0

ここには別の簡単な解決策があります。

私の特定の状況は、スーパークラスの「BeforeClass」が実行される前に、サブクラスの「BeforeClass」からモック サービスを注入する必要があるということです。

これを行う@ClassRuleには、サブクラスで a を使用するだけです。

例えば:

@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
    }
};

これが役立つことを願っています。これにより、静的セットアップを「逆」の順序で効果的に実行できます。

于 2017-03-22T09:47:54.830 に答える
-1

私の場合 (JUnit) では、基本クラスと派生クラスに setup() という同じメソッドがあります。この場合、派生クラスのメソッドのみが呼び出され、基本クラスのメソッドを呼び出すようにしています。

于 2013-03-13T18:58:56.213 に答える