TestNG テスト ケースでクラス全体のグループを指定できますか?
質問
TestNG にデータベース テストを表す基本クラスがあり、このクラスから拡張するすべてのクラスがグループ「db-test」に属することを指定したいのですが、これは不可能であることがわかりました。@Test アノテーションを試してみました。
@Test(groups = { "db-test" })
public class DBTestBase {
}
ただし、 @Test アノテーションが多数のメソッドをテストに作成しようとし、テストの実行時に Eclipse に警告/エラーがポップアップ表示されるため、これは機能しません。
そこで、少なくともグループが割り当てられるようにテストを無効にしてみました。
@Test(enabled = false, groups = { "db-test" })
public class DBTestBase {
}
ただし、 @BeforeTest (および他の同様のアノテーション) も無効になります...もちろんそれは私が望んでいることではありません。
クラスに特定のタイプのグループとしてアノテーションを付ける何らかの方法が欲しいのですが、TestNG ではそれは完全には不可能のようです。他に何かアイデアがある人はいますか?
解決
答えは習慣を通してです org.testng.IMethodSelector:
その includeMethod() アノテーションのないパブリックメソッドなど、必要なメソッドを除外できます。
ただし、カスタムを登録するには ジャワ MethodSelector を XMLテスト 任意の TestRunner によって管理されるインスタンス。つまり、独自のインスタンスが必要です。 カスタム テストランナー.
ただし、カスタム TestRunner を構築するには、 テストランナーファクトリー, 、 を通って -テストランファクトリー オプション。
ただし、 -testrunfactory は決して考慮されません。 テストNG クラス...したがって、カスタム TestNG クラスも定義する必要があります。
- configure(Map) メソッドをオーバーライドするには、
- したがって、実際に TestRunnerFactory を設定できます
- TestRunnerFactory はカスタム TestRunner を構築します。
- XMLTest インスタンスにカスタム XMLMethodSelector を設定する TestRunner
- カスタム IMethodSelector を構築する XMLMethodSelector
- IMethodSelector は、選択した TestNG メソッドを除外します。
わかりました...それは悪夢だ。しかし、これはコードチャレンジでもあるので、少し難しいはずです ;)
すべてのコードは次の場所で入手できます。 DZone スニペット.
コードチャレンジの場合はいつものように:
- 1 つの Java クラス (およびかなりの数の内部クラス)
- クラスを「source/test」ディレクトリにコピーして貼り付けます(パッケージが「test」であるため)
- 実行します(引数は必要ありません)
マイク・ストーンからのアップデート:
これは私が最終的にやったことにかなり近いように聞こえるので受け入れるつもりですが、私がやったことも追加しようと思いました。
基本的に、テスト (およびその他) アノテーションのグループ プロパティのように動作するグループ アノテーションを作成しました。
次に、GroupsAnnotationTransformer を作成しました。これは IAnnotationTransformer を使用して、定義されているすべてのテストとテスト クラスを確認し、テストを変更してグループを追加します。これは、グループの除外と包含で完全に機能します。
新しいアノテーション トランスフォーマーを使用するようにビルドを変更すると、すべて完璧に動作します。
良い...1 つの注意点は、グループをテスト以外のメソッドに追加しないことです。なぜなら、これを行った時点では、何でも変換できる別のアノテーション トランスフォーマーがあったのですが、何らかの理由で、それは私が使用していた TestNG には含まれていませんでした...したがって、アノテーションの前後のメソッドを alwaysRun=true にすることをお勧めします。私にとってはそれで十分です。
最終的な結果として、次のことができるようになります。
@Groups({ "myGroup1", "myGroup2"})
public class MyTestCase {
@Test
@Groups("aMethodLevelGroup")
public void myTest() {
}
}
そして、サブクラス化などすべてを使用してトランスフォーマーが機能するようにしました。
他のヒント
TestNG は、@Test アノテーションが付いたクラスからすべてのパブリック メソッドを実行します。TestNG で実行したくないメソッドを非公開に変更できるかもしれません
それは私には次のように思われるでしょう コードチャレンジ (コミュニティウィキ投稿):
以下を行わずに、グループ「aGlobalGroup」の拡張クラスのすべてのテスト メソッドを実行できるようにする方法:
- Extended クラス自体に「aGlobalGroup」グループを指定しますか?
- Extended クラスのアノテーションのないパブリック メソッドをテストしますか?
最初の答えは簡単です。
基本クラスレベルにクラス TestNG(groups = { "aGlobalGroup" }) を追加します
このグループは、基本クラスと拡張クラスの両方のすべてのパブリック メソッドに適用されます。
しかし:testng ではないパブリック メソッド (TestNG アノテーションなし) もそのグループに含まれます。
チャレンジ:それらの非 TestNG メソッドを含めることは避けてください。
@Test(groups = { "aGlobalGroup" })
public class Base {
/**
*
*/
@BeforeClass
public final void setUp() {
System.out.println("Base class: @BeforeClass");
}
/**
* Test not part a 'aGlobalGroup', but still included in that group due to the class annotation. <br />
* Will be executed even if the TestNG class tested is a sub-class.
*/
@Test(groups = { "aLocalGroup" })
public final void aFastTest() {
System.out.println("Base class: Fast test");
}
/**
* Test not part a 'aGlobalGroup', but still included in that group due to the class annotation. <br />
* Will be executed even if the TestNG class tested is a sub-class.
*/
@Test(groups = { "aLocalGroup" })
public final void aSlowTest() {
System.out.println("Base class: Slow test");
//throw new IllegalArgumentException("oups");
}
/**
* Should not be executed. <br />
* Yet the global annotation Test on the class would include it in the TestNG methods...
*/
public final void notATest() {
System.out.println("Base class: NOT a test");
}
/**
* SubClass of a TestNG class. Some of its methods are TestNG methods, other are not. <br />
* The goal is to check if a group specify in the super-class will include methods of this class. <br />
* And to avoid including too much methods, such as public methods not intended to be TestNG methods.
* @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a>
*/
public static class Extended extends Base
{
/**
* Test not part a 'aGlobalGroup', but still included in that group due to the super-class annotation. <br />
* Will be executed even if the TestNG class tested is a sub-class.
*/
@Test
public final void anExtendedTest() {
System.out.println("Extended class: An Extended test");
}
/**
* Should not be executed. <br />
* Yet the global annotation Test on the class would include it in the TestNG methods...
*/
public final void notAnExtendedTest() {
System.out.println("Extended class: NOT an Extended test");
}
}
@Test アノテーションをメソッド レベルで指定できるため、最大限の柔軟性が得られます。
public class DBTestBase {
@BeforeTest(groups = "db-test")
public void beforeTest() {
System.out.println("Running before test");
}
public void method1() {
Assert.fail(); // this does not run. It does not belong to 'db-test' group.
}
@Test(groups = "db-test")
public void testMethod1() {
Assert.assertTrue(true);
}
}
これでうまくいきますか、それともあなたの質問に何かが欠けていますか。