TestNGがインタリーブの代わりにテストクラスのメソッドを連続して実行するようにするには?

状況と問題

私はいくつかのテストクラスを持っていて、それぞれにいくつかのテストメソッドがあります。すべてのテストは、バックグラウンドで同じテストデータベースを使用します。各テストクラスは、データベースの内容を初期化し、いくつかのテストメソッドでテストします。

それぞれのテストを個別に実行すると、すべてが合格になります。しかし、同時にいくつかのテストを実行すると(MavenまたはIDE、IntelliJを使用)、異なるテストクラスのメソッドがインターリーブされて実行されます。第2クラスのデータベース初期化は、第1クラスの開始後、第1クラスのすべてのテストメソッドが実行される前に実行されるので、これらのメソッドは失敗します(データベースには既に第2クラスのデータが含まれています)。

私が試したことのいくつかと、いくつかの詳細

最も簡単な解決策は、TestNGランナーにクラスを連続して実行させることです(つまり、テストクラスのすべてのテストメソッドが終了してから別のクラスのテストメソッドが実行されるまで待つ)。これはできますか?

おそらく私のスイートで別のテストとして各クラスを指定することでこれを行うことができますが、これはやりたくありません。これは、不器用でエラーのあるテストクラスを追加するたびにスイートに何かを追加する必要があることを意味します-prone。

メソッドがまだ(ただし同時にではありませんが)間違った順序で実行されるため、何かを並列化しないように(例えば、スレッド数を1に設定する、または並列実行を無効にする)

1つのオプションは、各テストクラスに異なるデータベースを使用することですが、JPAとGuiceを使用してこれを行う簡単な方法はありません。

私は現在DBUnit、Unitilsなどを使用していません。私はこれらのツールをよく知っていませんが、私は自分の問題を解決しないという印象を受けました。

私は、各テストクラスでデータベースを初期化するためにJPAを使用しています(つまり、エンティティオブジェクトを作成し、それらを保持しています)。

11
少なくともいくつかのクラスには、 testPrepareDb というメソッドと、 @Test(dependsOnMethods = "testPrepareDb")というアノテーションが付けられたメソッドがあることが問題の少なくとも一部だと思います。いくつかのクラスが1つのテストの一部として実行されると、すべての依存メソッドがすべての testPrepareDb メソッドが実行された後にのみ実行されるようです。基本的には、私のテストクラスをスイートXMLに として明示的に記述することなく、TestNGテストを自動的に別々のものに翻訳しておきたいだけです。
追加された 著者 mazi,

7 答え

Even in sequential mode TestNG could interleave test methods from the same suite. It does guarantee the sequence @BeforeClass -> @Test -> @AfterClass but it can do something like:

before class1
    test class1.method1
before class2
    test class2.method1
    test class1.method2
after class1
    test class2.method2
after class2

解決方法は、各クラスを異なるスイートに強制することです(真に順次実行されます)。バージョン2.16以降、Mavenのsurefireプラグインは、各クラスを別のスイートに入れて、問題を修正しました。

一方、IDEA(最新の13 EAPでも)は、同じスイート内のすべてのクラスを含むxmlファイルを生成します。うまくいけば、IDEAはこれに追随してこれを修正するでしょう。インターリーブされたテストは、データベースなどの共有リソースを使用して作業を行う場合に非常に役立ちます。

5
追加された
特別な設定は必要ありません。私はスイートのXMLなどを使用していません。私はファイルパターンをsurefire設定で指定します。更新:クラスを順番に実行するためにtestngにパッチを当てて、ルート全体を修正しましたが、まだプルリクエストの準備ができていません。
追加された 著者 Bogdan Calmac,
これは私にとってもうまくいかず、私は確実に2.17を使用しています。私は問題が彼の元の質問の下の彼のコメントの中に記述された@ maziであると思います。同じ名前の複数のメソッドがあっても、異なるクラスであっても、その一つに依存する場合、TestNGはこれをすべてそれら。しかしこれは推測ですが、私はすでに相互依存関係にあるすべての方法をまとめて勉強していますので、これ以上調べる時間がなくなりました。
追加された 著者 Dan King,
2.16の新機能についてのヒントをありがとう!私はそれが動作するように見えることはできません。特別な設定が必要ですか? ドキュメントのパラレルなどのパラメータ関連していないようです(とにかくJUnitのようです)。
追加された 著者 mazi,

TestNGにはいくつかの平行した戦略があります。 methods はあなたのニーズには積極的ですが、 classes や多分 instances を見てきましたか?

1
追加された
あなたが必要とする戦略は、「同じクラスに属している限り、並列にメソッドを実行する」ため、マルチスレッドのチューニングは役に立ちません。それは利用できません。
追加された 著者 patrungel,
前に false してみました。今では methodsclassestestsinstances は有効なオプションではないようです)を試しました。何も助けません。私が書いたように、問題は並列化ではなく、順序付けされています。
追加された 著者 mazi,

ここにも同様の問題がありました。私は、グループごとのインスタンス= "真"が解決策になると思います。

0
追加された

私は、TestNGのシーケンステストのいくつかの方法について議論した記事を書いた:

http://ancient-marinator.blogspot.com /2013/05/on-testing-scheduling-your-tests.html

Naturally, the best source for information is at home: http://testng.org/doc/index.html

0
追加された
TestNGで適用する必要がある唯一の順序は、最初のクラス @Test(groups = "test2"、dependsOnGroups)の先頭に @Test(groups = "test1") = "test1")など、順番に各クラスに適用されます。これはクラス単位で実行をシリアライズします。
追加された 著者 Bob Dalgleish,
@BobDalgleish - これはすべてのテストをグループに分けなければならないことを意味します。さらに重要なのは、他のクラスも実行されなくても、自分のクラスを自分で実行できないということです。
追加された 著者 Dan King,
ありがとう、これは良いブログ記事です。それは非常に一般的ですが、私の特定の問題に対処していません。
追加された 著者 mazi,

We were running into this same issue, most people say it's caused by using dependsOn, but our solution was just setting priorities at a test level for some of our tests. I set up a Test Listener to re-prioritize our tests so that they run in the correct order. This is based on saberduck's solution in https://github.com/cbeust/testng/issues/106

このソリューションは、テスト優先度をクラス優先度に連結することによってテスト優先度を保持します。

package testng_Listeners;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import org.testng.IAnnotationTransformer;
import org.testng.Reporter;
import org.testng.annotations.ITestAnnotation;

//Listener to fix TestNG Interleaving issue. I had to re-write this as the original example I had did not allow for priority to be manually set on a test level.
public class RePrioritizingListener implements IAnnotationTransformer {

HashMap priorityMap = new HashMap(); Integer class_priorityCounter = 10000; // The length of the final priority assigned to each method. Integer max_testpriorityLength = 4; @Override public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { // class of the test method. Class<?> declaringClass = testMethod.getDeclaringClass(); // Current priority of the test assigned at the test method. Integer test_priority = annotation.getPriority(); // Current class priority. Integer current_ClassPriority = priorityMap.get(declaringClass); if (current_ClassPriority == null) { current_ClassPriority = class_priorityCounter++; priorityMap.put(declaringClass, current_ClassPriority); } String concatenatedPriority = test_priority.toString(); // Adds 0's to start of this number. while (concatenatedPriority.length() < max_testpriorityLength) { concatenatedPriority = "0" + concatenatedPriority; } // Concatenates our class counter to the test level priority (example // for test with a priority of 1: 1000100001; same test class with a // priority of 2: 1000100002; next class with a priority of 1. 1000200001) concatenatedPriority = current_ClassPriority.toString() + concatenatedPriority; //Sets the new priority to the test method. annotation.setPriority(Integer.parseInt(concatenatedPriority)); String printText = testMethod.getName() + " Priority = " + concatenatedPriority; Reporter.log(printText); System.out.println(printText); } } 

また、リスナーをtestng.xmlに追加する必要があります





0
追加された

メソッドインターセプタ(=カスタムインターセプタの書き込みと有効化)を使用して、順序を制御します。

また、各クラスは独自のデータベースサンドボックスを使用する可能性があります。つまり、各テストクラスをトランザクションにラップすると役立つ可能性があります。

テーブル/ dbの個々の接尾辞を各クラスに設定すると、テストメソッドを並列に実行することもできます(最初の2つのオプションはないと思います)。

0
追加された

私はクラスレベルでdependsOnGroupsを使用しません。あなたが依存しているクラスのいずれかのテストメソッドが失敗すると、あなたのクラスはまったく動かないでしょう...これは 'dependsOn'グループの本当の欠点ですまたは方法)。最初に@Test(group = thisClassName)をクラスレベルで設定してから、testng.xmlファイルにテストタグ付きのクラスを指定してみます。次に、これらのテストのリストとしてxmlで実行されるクラスの順序付けを制御します。私は、XMLの次の上位タグでPreserveOrder = "True"を設定する必要があると思います。依存関係のために本当に必要な場合を除いてdependsOnの使用を避けますが、順序を制御するためには使用しません。お役に立てれば。 -JR

0
追加された