2012-12-09 3 views
6

Ich schreibe eine Testsuite für eine Webanwendung mit TestNG und Selenium WebDriver.TestNG Führen Sie alle Klassenmethoden mehrmals aus, indem Sie @BeforeClass mit den bereitgestellten Daten ausführen.

Was ich brauche ist, dass alle Methoden der Testklasse für verschiedene authentifizierte Benutzer mehrere Male ausgeführt werden (Daten werden zur Laufzeit aus einer DB herausgezogen). Also muss ich Daten an die Klasse mit Datenprovider übergeben, die Anmeldeinformationen aller Benutzer liefert, dann muss ich für jeden Benutzer einen Webtreiber erstellen (für die Reinheit des Experiments) und mit angegebenen Anmeldeinformationen in @BeforeClass Methode ausführen Alle @Test Methoden der Klasse und machen eine @AfterClass abreißen schließen Web-Treiber.

Wie kann ich das tun?

Meine Versuche, dies zu tun sind hier: https://gist.github.com/4246674

Attempt1 eine @Test(dataProvider="getUsersIdAndName") auf Klasse zu setzen war. Es funktioniert nicht, weil @Test(dataProvider=) für die Klasse nicht bedeutet, dass alle Methoden der Klasse mit den bereitgestellten Daten aufgerufen werden sollten. Das Ergebnis war, dass die Methode überhaupt nicht aufgerufen wurde, da keine Daten an die Argumente übergeben werden konnten. Und ich bekomme seltsamen Testbericht, wo diese Methode als mit Ausführungszeit von 0 Sekunden übergeben markiert ist. (Es ist ein Maven-Projekt in NetBeans geöffnet, wenn dies sinnvoll ist.)

Ist @Test(dataProvider=) auf der Klasse bedeutet überhaupt etwas?

Versuch2 war DataProvider auf der @Test Annotation der Methode hinzuzufügen. Es funktioniert nicht, da die Testmethode während des einzelnen Klassenlaufs zweimal aufgerufen wird. Das Ergebnis war, dass es beim zweiten Mal fehlschlägt, weil es versucht, den Test zu wiederholen, während der Web-Treiber nicht neu initialisiert wurde: Der Browser rendert bereits eine andere Seite.

Auch gibt es Nachteile der ersten und zweiten Versuch, die Anmeldung selbst erfolgt in der Testmethode eher, dass in @BeforeClass Methode, weil ich keine Möglichkeit kenne, es mit Daten von Datenanbieter zu liefern.

Versuch3 war ein verzweifelter Versuch, @BeforeClass und @Test mit der einzigen Methode zu kombinieren. Es funktioniert nicht, da @BeforeClass auch @Parameters fordert, wenn eine annotierte Methode eine Parameterliste hat. Das Ergebnis ist, dass diese Methode dreimal aufgerufen wird: zum ersten Mal als ein Klassensetup, wenn es aus dem obigen Grund fehlschlägt, und zweimal wegen des Datenproviders, wenn es erfolgreich ist.

Dann fand ich heraus, dass TestNG keinen Weg nicht bieten alle Klassenmethoden mehrmals mit verschiedenen Daten aufzurufen: http://comments.gmane.org/gmane.comp.java.testng.user/864

Ich habe zwei andere Ideen, wie kann ich den gleichen Effekt zu archivieren.

Idea4 ist eine @Test(dataProvider=) auf jeder Testmethode zu platzieren, führt jede Methode eine Authentifizierung und isAuthenticated() Test von selbst und führen Sie dann einen eigenen Test. Ineffektiv und hässlich.

Idea5, das aussieht wie das beste erschwingliche ist mit einer @Test nur eine Methode zu markieren, die alle anderen Testmethoden aggregiert: es empfängt Daten vom Datenprovider, führt Authentifizierung durch gegebenen Benutzer durch, führt dann isAuthenticated Test und alle anderen notwendigen Tests.In diesem Fall @BeforeClass und @AfterClass nur Web-Treiber einrichten und abbauen. Dieser Ansatz hat den Nachteil, dass ich die Möglichkeit verliere, @BeforeMethod und @AfterMethod zu verwenden, aber das ist für mich erschwinglich: sieht so aus, als würde ich sie nicht brauchen.

Gibt es eine bessere Möglichkeit, denselben Effekt zu archivieren?

Sorry für lange Nachricht.

Vielen Dank im Voraus.

Antwort

8

Sie können versuchen, Factory für Ihre Bedürfnisse zu erkunden. Factory würde es Ihnen ermöglichen, alle mit @Test einer Klasse annotierten Methoden mit anderen Daten auszuführen. Sie können in diesem Fall Ihren Webdriver in Ihrer Vorklasse initialisieren. Erläuterung here.

+0

Danke. Hat geschafft, genau das zu tun, was ich wollte. Platzierte eine '@ Factory' Annotation für den Konstruktor und ließ sie Daten vom Datenprovider empfangen. Jede Instanz der Testklasse stellt jetzt einen Webtreiber dar, der als ein Benutzer angemeldet ist, der eine Reihe von Tests durchführt. Konstruktor lädt Eigenschaften und speichert angegebene Benutzeranmeldeinformationen in Klassenfeldern. Die '@ BeforeClass'-Methode instanziiert den Webtreiber und meldet sich mit den gespeicherten Anmeldeinformationen an. '@ AfterClass' schließt den Web-Treiber. Wenn jemand interessiert ist, ist der vollständige Code hier. – yaromir

2

Okay, lassen Sie mich versuchen, Ihre Fragen basierend auf meiner Erfahrung mit testNG und Webdriver zu beantworten.

Frage: Bedeutet @Test (dataProvider =) für die Klasse überhaupt etwas?
A. Nein. DataProvider ist eine Annotation auf Methodenebene und keine Klassenebene. Wie erwähnt here. Es sollte eine Methode sein, die die Daten für die Testmethode im Object [] [] -Format bereitstellt.

Q. Wie erreicht man das von Ihnen erwähnte Szenario? (Angenommen, ich habe Ihr Szenario verstanden.)
A. Sie sollten @BeforeMethod und nicht @BeforeClass zum Instanziieren des Webdriver-Objekts verwenden. Auf diese Weise können Sie für jede Methode ein anderes WD-Objekt erstellen. Und dataProvider kann mehrere Daten an die isAuthenticated() -Methode übergeben. Wenn Sie eine Konfigurationsdatei auf Klassenebene übergeben möchten, können Sie @BeforeClass nur mit der Logik zum Laden von Eigenschaftsdateien speichern. Diese Eigenschaftendatei wird also einmal für die gesamte Klasse geladen. Natürlich sollten Sie auch @AfterMethod verwenden, um das webdriver-Objekt zu schließen.

+0

Danke für die Antwort. Ich dachte auch an diese Lösung (Idee №4), entschied aber, dass es ineffektiv ist, weil es redundant ist, Webtreiber zu instanziieren und sich vor jeder Testmethode einzuloggen, weil es im Idealfall einmal pro Test genügt Methoden in der Klasse. Ich muss nur alle Aktionen mehrmals mit verschiedenen Instanzen von Web-Treiber als verschiedene Benutzer angemeldet ausführen. Danke trotzdem. Habe nützliche Informationen bekommen. – yaromir

Verwandte Themen