2017-04-23 2 views
0

Ich schreibe eine Testsuite mit WebDriver in Java. Wichtig ist, dass die Tests Funktionstests sind, keine Unit-Tests. Häufig wird derselbe Testfall mehrmals nacheinander mit verschiedenen Daten ausgeführt, z. B. "Anwendung erstellen" mit unterschiedlichen Namen und Komponenten für jede Anwendung.Java, WebDriver, bestätigt/Ausnahmen und UI-Status

Der Testfall-Ausführungspfad enthält einige Dialogfelder. Bei jedem Dialog kann ein Fehler auftreten (z. B. "Komponente nicht gefunden"). Derzeit behandelt meinen Code die Fehler direkt neben wo sie passieren - zum Beispiel: (dies ist ein vereinfachtes Beispiel nicht ein Stück Produktionscode, es wurde nicht geprüft, so wenden Sie sich bitte triviale Fehler verzeihen)

WebElement component; 
try { 
    component = componentsDialog.findElement(By.xpath("@class='component' and @componentId = '" + componentId + "']")); 
} catch (NoSuchElementException nse) { 
    log.error("Component not found"); 
    driver.switchTo().activeElement().sendKeys(Keys.ESCAPE); 
    stoppedOnError = true; 
    return; 
} 
component.click(); 
WebElement buttonAdd = 
componentsDialog.findElement(By.className("addbutton")); 
buttonAdd.click(); 

Dies ist nicht sehr Java-ähnlich für die Fehlerbehandlung. Es könnte schwierig sein, in TestNG zu integrieren, wenn ich das in Zukunft verwenden möchte.

Aber ich kann dies nicht einfach dem allgemeinen NoSuchElementException-Handler für den Testfall überlassen. Meistens bedeutet NoSuchElementException, dass sich die Benutzeroberfläche geändert hat (oder ich habe einen Fehler im Testcode gemacht). In diesem Fall bedeutet dies, dass die spezielle Konfiguration für diese Instanz des Testfalls falsch ist. Und diese Konfiguration wird vom Benutzer festgelegt. Es ist ein anderer Fehler und sollte anders gemeldet werden.

So konnte ich nur die Ausnahme fangen und eine weitere, mit der richtigen Nachricht ... Aber beachten Sie den Teil, wo die Escape-Taste gedrückt wird. Ich schließe den Komponentenauswahldialog, so dass der Zustand der Benutzeroberfläche der gleiche ist wie bei einer erfolgreichen Komponentenauswahl. Im Rest dieses Testfalls ist dieser spezielle Dialog nicht geöffnet. Wie also würde der Ausnahmebehandler (am Ende der Testfallmethode oder im Aufrufer) wissen, in welchem ​​Zustand sich die UI gerade befindet und was sie zur Wiederherstellung tun muss?

(Autodetection ist möglich, aber flockig, da es darauf angewiesen wäre, das Vorhandensein eines Elements zu erkennen, das für jeden möglichen Dialog eindeutig ist).

Also was mache ich hier, um die Fehlerbehandlung außerhalb des unmittelbaren Ausführungsstromes zu ermöglichen? Irgendwo eine Zustandsverfolgungsvariable behalten? Dies scheint sehr fehleranfällig zu sein.

Ich könnte natürlich versuchen, auf das Page Object Model zu wechseln. Das Modell erscheint mir als sehr schwer, erfordert eine Zunahme der Codezeilen um bis zu einer Größenordnung und zahlt sich nur dann aus, wenn viele verschiedene Testfälle die gleichen Kontrollen verwenden. (In meinen Fällen verwenden unterschiedliche Use Cases normalerweise unterschiedliche UI-Elemente, daher verstehe ich nicht, wie sich das Modell auszahlen würde).

Vielleicht ist dieser Eindruck falsch. Aber selbst wenn ich das Modell verwende, ist jede Seite ein nicht verwandtes Objekt - woher weiß ich, welche Seite gerade aktiv ist? Das Aufrufen von Methoden einer Seite, wenn eine andere Seite aktiv ist, führt nur zu bedeutungslosen Ausnahmen (wenn keine komplizierte Erkennungslogik vorhanden ist).

Antwort

0

Wenn ich diesen Code schreiben würde, würde ich es so schreiben.

List<WebElement> component = componentsDialog.findElements(By.xpath("@class='component' and @componentId = '" + componentId + "']")); 
if (component.isEmpty()) 
{ 
    log.error("Component not found"); 
    driver.switchTo().activeElement().sendKeys(Keys.ESCAPE); 
    componentsDialog.findElement(By.className("addbutton")).click(); 
} 
else 
{ 
    component.get(0).click(); 
} 

Sie müssen (und IMO sollte nicht) keine Ausnahmen hier werfen. Wenn Sie bei the docs aussehen heißt es

findElement sollte nicht Gebrauch findElements für nicht vorhandene Elemente suchen verwendet werden (By) und Null-Länge Antwort stattdessen behaupten.

Oh ... und zu Ihrem Kommentar über Seitenobjekte. Es sollte nicht viel zusätzlichen Code erfordern ... definitiv keine Größenordnungen mehr, wenn richtig gemacht.Was es Ihnen bringt, ist eine bessere Organisation, bessere Wiederverwendung von Code, weniger Wartungsaufwand und so weiter. Wenn Sie Ihren gesamten Code für eine Seite oder einen Dialog in eine einzige Klasse einfügen, ist es viel einfacher, Skripte zu aktualisieren, wenn sich Dinge ändern oder wenn ein Fehler behoben werden muss. Es wird Ihren Wartungsaufwand drastisch reduzieren.

+0

Ändern Sie die findElement-Methode zu findElements – Grasshopper

+0

Damit Ihr Beispiel genauso funktioniert wie ich, müssten wir die letzte Zeile in den else-Block verschieben. Beachten Sie die Rückgabeanweisung in meinem Beispiel. –

+0

Und im wirklichen Leben beendet das Klicken auf die Schaltfläche Hinzufügen den Testfall nicht. Im Testfall gibt es mehrere Überprüfungen wie diese, so dass ich den letzten Teil ziemlich weit eingezogen habe. Ich benutze Return-Anweisungen, um das zu vermeiden. –