Ich habe eine abstrakte Basisklasse, die ich als Basis für meine Unit-Tests verwende (TestNG 5.10). In dieser Klasse initialisiere ich die gesamte Umgebung für meine Tests, das Einrichten von Datenbankzuordnungen usw. Diese abstrakte Klasse verfügt über eine Methode mit einer @BeforeClass
Anmerkung, die die Initialisierung durchführt.
Als nächstes erweitere ich diese Klasse um bestimmte Klassen, in denen ich @Test
Methoden und auch @BeforeClass
Methoden habe. Diese Methoden führen eine klassenspezifische Initialisierung der Umgebung durch (z. B. einige Datensätze in die Datenbank einfügen).
Wie kann ich eine bestimmte Reihenfolge der mit @BeforeClass
Anmerkungen versehenen Methoden erzwingen ? Ich brauche diejenigen aus der abstrakten Basisklasse, die vor denen der erweiterten Klasse ausgeführt werden sollen.
Beispiel:
abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@BeforeClass
doSpecificInitialization() {...}
@Test
doTests() {...}
}
Erwartete Bestellung:
A.doInitialization
B.doSpecificInitialization
B.doTests
Aktuelle Bestellung:
B.doSpecificInitialization // <- crashes, as the base init is missing
(A.doInitialization // <---not executed
B.doTests) // <-/
quelle
dependsOnMethods
Problemumgehung hat es geschafft. Obwohl ich einen "Superclass First" -Ansatz vorziehen würde ...edit: Die Antwort unten ist für JUnit , aber ich werde sie trotzdem hier lassen, weil sie hilfreich sein könnte.
Laut der JUnit-API : "Die @ BeforeClass-Methoden von Oberklassen werden vor denen der aktuellen Klasse ausgeführt."
Ich habe das getestet und es scheint für mich zu funktionieren.
Wie @Odys weiter unten erwähnt, müssen für JUnit die beiden Methoden unterschiedlich benannt sein. Andernfalls wird nur die Unterklassenmethode ausgeführt, da das übergeordnete Verfahren schattiert wird.
quelle
Ich
public
habe der abstrakten Klasse hinzugefügt und TestNG (6.0.1) hat zuvor die doInitialization () ausgeführtdoTests
. TestNG wird nicht ausgeführt,doInitialization()
wenn ichpublic
aus Klasse A entferne .quelle
B
auch eine@BeforeClass
Methode mit Annotation hat, wie im Fall des OP.Ich habe gerade Ihr Beispiel mit 5.11 ausprobiert und bekomme zuerst die @BeforeClass der Basisklasse aufgerufen.
Können Sie Ihre Datei testng.xml veröffentlichen? Vielleicht geben Sie dort sowohl A als auch B an, während nur B erforderlich ist.
Fühlen Sie sich frei, die Mailingliste der Test-Benutzer zu verfolgen, und wir können Ihr Problem genauer untersuchen.
- Cedric
quelle
Ich habe das gerade durchgesehen und einen weiteren Weg gefunden, dies zu erreichen. Verwenden Sie einfach
alwaysRun
auf@BeforeClass
oder@BeforeMethod
in der abstrakten Klasse, funktioniert wie erwartet.quelle
Wenn ich laufe von: JUnitCore.runClasses (TestClass.class); Das übergeordnete Element wird vor dem untergeordneten Element ordnungsgemäß ausgeführt. (Sie benötigen super.SetUpBeforeClass () nicht. ) Wenn Sie es über Eclipse ausführen: Aus irgendeinem Grund kann die Basisklasse nicht ausgeführt werden. Die Problemumgehung : Rufen Sie die Basisklasse explizit auf: ( BaseTest.setUpBeforeClass (); ) Möglicherweise möchten Sie ein Flag in der Basisklasse haben, falls Sie es von einer Anwendung aus ausführen, um festzustellen, ob es bereits eingerichtet ist oder nicht. Es wird also nur einmal ausgeführt, wenn Sie es über beide möglichen Methoden ausführen (z. B. von Eclipse für persönliche Tests und über ANT für eine Build-Version).
Dies scheint ein Fehler mit Eclipse oder zumindest unerwartete Ergebnisse zu sein.
quelle
Für JUnit : Wie @fortega erwähnt hat: Laut JUnit-API: "Die @ BeforeClass-Methoden von Oberklassen werden vor denen der aktuellen Klasse ausgeführt."
Achten Sie jedoch darauf, nicht beide Methoden mit demselben Namen zu benennen . Da in diesem Fall die übergeordnete Methode vom untergeordneten übergeordneten Element ausgeblendet wird. Quelle .
quelle
Wie wäre es, wenn Ihre @ BeforeClass-Methode eine leere spezifischeBeforeClass () -Methode aufruft, die möglicherweise von Unterklassen wie folgt überschrieben wird oder nicht:
quelle
dependsOnMethod
kann verwendet werden.zB im Falle von Spring (
AbstractTestNGSpringContextTests
)quelle
Überprüfen Sie Ihre Importanweisung. Es sollte sein
import org.testng.annotations.BeforeClass;
nicht
import org.junit.BeforeClass;
quelle
Das funktioniert bei mir -
quelle
Warum versuchen Sie nicht, eine abstrakte Methode doSpecialInit () in Ihrer Superklasse zu erstellen, die von Ihrer kommentierten BeforeClass-Methode in der Superklasse aufgerufen wird?
Entwickler, die Ihre Klasse erben, müssen diese Methode implementieren.
quelle
Hier gibt es eine andere einfache Lösung.
Meine besondere Situation ist, dass ich Mock-Services von "BeforeClass" in die Unterklasse einfügen muss, bevor "BeforeClass" in der Oberklasse ausgeführt wird.
Verwenden Sie dazu einfach ein
@ClassRule
in der Unterklasse.Beispielsweise:
Ich hoffe das hilft. Dies kann das statische Setup effektiv in "umgekehrter" Reihenfolge ausführen.
quelle
Ich hatte heute ein ähnliches Problem. Der einzige Unterschied war, dass eine Basisklasse nicht abstrakt war
Hier ist mein Fall
Es kam vor, dass eine
@BeforeClass
Methode aus Klasse A nie ausgeführt wurde.Das Spiel mit der Privatsphäre Modifikatoren fand ich , dass TestNG nicht ausführen eine
@BeforeClass
kommentierte Methode von vererbten Klasse , wenn eine Methode nicht sichtbar von einer Klasse-Erbin istDas wird also funktionieren:
Infolgedessen passiert Folgendes:
quelle
In meinem Fall (JUnit) habe ich die gleichen Methoden wie setup () in der Basisklasse und der abgeleiteten Klasse. In diesem Fall wird nur die Methode der abgeleiteten Klasse aufgerufen, und ich habe sie die Basisklassenmethode aufrufen lassen.
quelle
Ein besserer und sauberer Weg, dies mithilfe der Vererbung zu erreichen, könnte folgender sein:
quelle