Frage

Ich habe eine Basisklasse, die einen Datenbanktest in TestNG darstellt, und ich möchte angeben, dass alle von dieser Klasse ausgehenden Klassen zu einer Gruppe „db-test“ gehören. Ich habe jedoch festgestellt, dass dies nicht möglich zu sein scheint.Ich habe die @Test-Annotation ausprobiert:

@Test(groups = { "db-test" })
public class DBTestBase {
}

Dies funktioniert jedoch nicht, da die @Test-Annotation versucht, eine Reihe von Methoden in Tests umzuwandeln, und in Eclipse Warnungen/Fehler angezeigt werden, wenn die Tests ausgeführt werden.

Also habe ich versucht, den Test zu deaktivieren, damit zumindest die Gruppen zugewiesen werden:

@Test(enabled = false, groups = { "db-test" })
public class DBTestBase {
}

aber dann werden auch alle @BeforeTest (und andere ähnliche Anmerkungen) deaktiviert ...Das ist natürlich nicht das, was ich will.

Ich hätte gerne eine Möglichkeit, eine Klasse als zu einem bestimmten Gruppentyp gehörend zu kommentieren, aber das scheint in TestNG nicht ganz möglich zu sein.Hat jemand noch andere Ideen?

War es hilfreich?

Lösung

Die Antwort liegt in einem Brauch org.testng.IMethodSelector:

Es ist includeMethod() kann jede gewünschte Methode ausschließen, z. B. eine öffentliche, nicht annotierte Methode.

Um jedoch einen Brauch zu registrieren Java MethodSelector, Sie müssen es dem hinzufügen XMLTest Instanz, die von einem beliebigen TestRunner verwaltet wird, was bedeutet, dass Sie Ihre eigene benötigen benutzerdefinierter TestRunner.

Um jedoch einen benutzerdefinierten TestRunner zu erstellen, müssen Sie einen registrieren TestRunnerFactory, durch das -testrunfactory Möglichkeit.

ABER das -testrunfactory wird von NIEMALS berücksichtigt TestNG Klasse...Sie müssen also auch eine benutzerdefinierte TestNG-Klasse definieren:

  • um die configure(Map)-Methode zu überschreiben,
  • Sie können also die TestRunnerFactory tatsächlich festlegen
  • TestRunnerFactory, die Ihnen einen benutzerdefinierten TestRunner erstellt,
  • TestRunner, der für die XMLTest-Instanz einen benutzerdefinierten XMLMethodSelector festlegt
  • XMLMethodSelector, der einen benutzerdefinierten IMethodSelector erstellt
  • IMethodSelector, der alle TestNG-Methoden Ihrer Wahl ausschließt!

OK...es ist ein Albtraum.Aber es ist auch eine Code-Herausforderung, also muss es eine kleine Herausforderung sein ;)

Der gesamte Code ist unter verfügbar DZone-Schnipsel.

Wie bei einer Code-Challenge üblich:

  • eine Java-Klasse (und einige innere Klassen)
  • Kopieren Sie die Klasse und fügen Sie sie in ein Verzeichnis „source/test“ ein (da das Paket „test“ ist).
  • Führen Sie es aus (keine Argumente erforderlich)

Update von Mike Stone:

Ich werde das akzeptieren, weil es ziemlich nah an dem klingt, was ich letztendlich getan habe, aber ich dachte, ich würde auch hinzufügen, was ich getan habe.

Im Grunde habe ich eine Gruppenanmerkung erstellt, die sich wie die Gruppeneigenschaft der Testanmerkungen (und anderer Annotationen) verhält.

Dann habe ich einen GroupsAnnotationTransformer erstellt, der IAnnotationTransformer verwendet, um alle definierten Tests und Testklassen zu überprüfen, und dann den Test ändert, um die Gruppen hinzuzufügen, was perfekt mit Gruppenausschluss und -einschluss funktioniert.

Ändern Sie den Build, um den neuen Anmerkungstransformator zu verwenden, und alles funktioniert perfekt!

Also...Die einzige Einschränkung besteht darin, dass die Gruppen nicht zu Nicht-Testmethoden hinzugefügt werden ...Denn zu der Zeit, als ich das gemacht habe, gab es einen anderen Annotationstransformator, mit dem man ALLES transformieren konnte, aber er war aus irgendeinem Grund nicht in dem TestNG enthalten, das ich verwendet habe ...Daher ist es eine gute Idee, Ihre Vorher/Nachher-Annotationsmethoden auf AlwaysRun=true zu setzen...was für mich ausreichend ist.

Das Endergebnis ist, dass ich Folgendes tun kann:

@Groups({ "myGroup1", "myGroup2"})
public class MyTestCase {
    @Test
    @Groups("aMethodLevelGroup")
    public void myTest() {
    }
}

Und ich habe dafür gesorgt, dass der Transformator mit Unterklassen und allem funktioniert.

Andere Tipps

TestNG führt alle öffentlichen Methoden einer Klasse mit einer @Test-Annotation aus.Vielleicht könnten Sie die Methoden, die TestNG nicht ausführen soll, so ändern, dass sie nicht öffentlich sind

Mir kommt es wie folgt vor Code-Herausforderung (Community-Wiki-Beitrag):

So können Sie alle Testmethoden der Extended-Klasse aus der Gruppe „aGlobalGroup“ ausführen, ohne:

  • Angabe der Gruppe „aGlobalGroup“ in der Extended-Klasse selbst?
  • Testen nicht kommentierter öffentlicher Methoden der erweiterten Klasse?

Die erste Antwort ist einfach:
Fügen Sie eine Klasse TestNG(groups = { "aGlobalGroup" }) auf der Basisklassenebene hinzu

Diese Gruppe gilt für alle öffentlichen Methoden sowohl der Basisklasse als auch der erweiterten Klasse.

ABER:Auch öffentliche Methoden, die nicht testng sind (ohne TestNG-Annotation), werden in diese Gruppe aufgenommen.

HERAUSFORDERUNG:Vermeiden Sie die Einbeziehung dieser Nicht-TestNG-Methoden.

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

Ich bin mir nicht sicher, wie die Annotationsvererbung für TestNG funktioniert, aber das hier Artikel kann von Nutzen sein.

Eigentlich kann das sein besser helfen, schauen Sie sich inheritGroups an.

Sie können die @Test-Annotation auf Methodenebene angeben, um maximale Flexibilität zu gewährleisten.

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

Funktioniert das für Sie oder übersehe ich etwas in Ihrer Frage?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top