@BeforeClass und Vererbung – Reihenfolge der Ausführung

Lesezeit: 4 Minuten

Benutzer-Avatar
Dominik Sandjaja

Ich habe eine abstrakte Basisklasse, die ich als Grundlage für meine Komponententests verwende (TestNG 5.10). In dieser Klasse initialisiere ich die gesamte Umgebung für meine Tests, richte Datenbankzuordnungen ein usw. Diese abstrakte Klasse hat eine Methode mit a @BeforeClass Anmerkung, die die Initialisierung durchführt.

Als nächstes erweitere ich diese Klasse mit bestimmten Klassen, in denen ich habe @Test Methoden und auch @BeforeClass Methoden. Diese Methoden führen eine klassenspezifische Initialisierung der Umgebung durch (zB legen einige Datensätze in die Datenbank).

Wie kann ich eine bestimmte Anordnung der durchsetzen @BeforeClass kommentierte Methoden? Ich brauche diejenigen aus der abstrakten Basisklasse, die vor denen der Erweiterungsklasse ausgeführt werden.

Beispiel:

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

class B extends A {
    @BeforeClass
    doSpecificInitialization() {...}

    @Test
    doTests() {...}
}

Erwartete Bestellung:

A.doInitialization
B.doSpecificInitialization
B.doTests

Tatsächliche Bestellung:

B.doSpecificInitialization // <- crashes, as the base init is missing
(A.doInitialization        // <---not executed
 B.doTests)                // <-/

Benutzer-Avatar
Festung

bearbeiten: Antwort unten ist für JUnitaber ich werde es trotzdem hier lassen, weil es hilfreich sein könnte.

Laut dem 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 unten erwähnt, müssen Sie jedoch für JUnit die zwei unterschiedlich benannte Methoden Andernfalls wird jedoch nur die Methode der Unterklasse ausgeführt, da die übergeordnete Methode geschattet wird.

  • Obwohl die ursprüngliche Frage für TestNG war, bin ich hier angekommen, nachdem ich nach JUnit gegoogelt hatte, und Ihre Antwort hat geholfen – danke!

    – Teebote

    28. Januar 2011 um 12:28 Uhr

  • für JUnit dich brauchen Wenn Sie die beiden Methoden unterschiedlich benennen, führt dies jedoch dazu, dass nur die Methode der Unterklasse ausgeführt wird, da die übergeordnete Methode geschattet wird.

    – Odys

    30. Dezember 2016 um 18:01 Uhr

  • @Odys, vielen Dank für die Erwähnung. Ich hatte Mühe herauszufinden, warum die Methode “setup” in meiner Unterklasse lief, während die in ihrer Oberklasse nicht lief. Du hast mir gerade eine Menge Ärger erspart!

    – Tom Catullo

    17. August 2017 um 17:24 Uhr

  • Du hast meinen Tag gerettet. Vielen Dank!

    – Raubzüge

    28. Februar 2020 um 16:54 Uhr

Benutzer-Avatar
Bozo

Setzen Sie nicht die @BeforeClass auf der abstract Klasse. Nennen Sie es von jeder Unterklasse.

abstract class A {
    void doInitialization() {}
}

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

    @Test
    void doTests() {}
}

Scheint wie TestNG hat @BeforeClass(dependsOnMethods={"doInitialization"}) – Versuche es.

  • Das wollte ich im Grunde vermeiden: Methoden der super (abstrakten) Klasse müssen nicht explizit aufgerufen werden. Zumal ich auch Klassen habe, die von A erben, aber keine eigene @BeforeClass-Methode haben. Ich müsste nur eine für diesen Zweck einfügen.

    – Dominik Sandjaja

    25. Januar 2010 um 14:25 Uhr

  • Das dependsOnMethods Problemumgehung hat den Trick getan. Obwohl ich einen “Superclass First” -Ansatz bevorzugen würde …

    – Dominik Sandjaja

    25. Januar 2010 um 14:42 Uhr

  • Um “dependsOnMethod” zu verwenden, sollte “doInitialization” nicht mit “@Test” annotiert werden? Das ist ein Problem, da es technisch gesehen kein Test für sich ist …

    – N3da

    10. Oktober 2014 um 0:24 Uhr

  • @BeforeClass sollte eine statische Methode kommentieren

    – Fabrizio Stellato

    21. Februar 2019 um 13:56 Uhr

Benutzer-Avatar
Paul

Ich fügte hinzu public zur abstrakten Klasse und TestNG (6.0.1) hat vorher die doInitialization() ausgeführt doTests. TestNG wird nicht ausgeführt doInitialization() wenn ich entferne public ab Klasse A.

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

class B extends A {    
 @Test
 doTests() {...}
}

  • Das ist richtig, aber irrelevant. Das geht beim Unterricht nicht B Auch hat ein @BeforeClass-kommentierte Methode, wie im Fall des OP.

    – jpaugh

    24. Dezember 2015 um 17:31 Uhr


  • Ich tat das gleiche. Es scheint, dass die Reihenfolge der Vererbung fehlt, wenn die Basismethode privat ist. Vielen Dank!

    – Manuel

    2. Juni 2016 um 10:07 Uhr

Ich habe gerade Ihr Beispiel mit 5.11 ausprobiert und bekomme die @BeforeClass der Basisklasse, die zuerst aufgerufen wird.

Können Sie Ihre testng.xml-Datei posten? Vielleicht geben Sie dort sowohl A als auch B an, während nur B erforderlich ist.

Fühlen Sie sich frei, die Mailingliste testng-users zu verfolgen, und wir können uns Ihr Problem genauer ansehen.

– Cedric

Ich habe das gerade durchgemacht und einen weiteren Weg gefunden, dies zu erreichen. Benutz einfach alwaysRun an @BeforeClass oder @BeforeMethod in der abstrakten Klasse, funktioniert wie erwartet.

public class AbstractTestClass {
    @BeforeClass(alwaysRun = true)
    public void generalBeforeClass() {
        // do stuff
        specificBeforeClass();
    }
}

Benutzer-Avatar
Anatolii Stepaniuk

Für JUnit: Wie @fortega erwähnt hat: Laut der JUnit-API: “Die @BeforeClass-Methoden von Superklassen werden vor denen der aktuellen Klasse ausgeführt.”

Aber sei vorsichtig nicht beide Methoden mit demselben Namen zu benennen. Da in diesem Fall die Elternmethode von der untergeordneten Elternmethode ausgeblendet wird. Quelle.

Benutzer-Avatar
Markus Hall

Wenn ich weglaufe: JUnitCore.runClasses (TestClass.class);
Es wird das Elternteil vor dem Kind richtig ausführen (Sie brauchen es nicht super.SetUpBeforeClass();) Wenn Sie es von Eclipse aus 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 sie von einer Anwendung aus ausführen, um festzustellen, ob sie 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 zu sein oder zumindest unerwartete Ergebnisse.

1283770cookie-check@BeforeClass und Vererbung – Reihenfolge der Ausführung

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy