Ich versuche mein erstes Data Driven Test Framework zu erstellen, das Tests mit Selenium Grid / WebDriver auf mehreren Browsern ausführt. Im Moment habe ich jeden Testfall in seiner eigenen Klasse und parametriere den Browser, so dass jeder Testfall mit jedem Browser einmal ausgeführt wird.
Ist das bei großen Test-Frameworks üblich? Oder sollte jeder Testfall kopiert und auf jeden Browser in seiner eigenen Klasse abgestimmt werden? Also, wenn ich Chrome, Firefox und IE teste, sollte es Klassen für jedes geben, wie: "TestCase1Chrome", "TestCase1FireFox", "TestCase1IE"? Oder einfach "TestCase1" und parametriere den Test um 3 mal mit jedem Browser zu laufen? Ich frage mich nur, wie andere das machen.
Die Parametrisierung der Tests in einer einzelnen Klasse pro Testfall erleichtert die Pflege des nicht browserspezifischen Codes, während die Duplizierung von Klassen für jeden Browserfall die Pflege des browserspezifischen Codes erleichtert. Wenn ich browserspezifischen Code sage, z. B. ein Element anklicken. Auf ChromeDriver können Sie nicht in der Mitte einiger Elemente klicken, wo Sie auf FirefoxDriver können. Sie benötigen also möglicherweise zwei verschiedene Code-Blöcke, um auf ein Element zu klicken (wenn es in der Mitte nicht anklickbar ist).
Für diejenigen von Ihnen, die QA-Ingenieure beschäftigen, die Selen verwenden, was wäre hier die beste Praxis?
Ich arbeite derzeit an einem Projekt, das täglich etwa 75k - 90k Tests durchführt. Wir übergeben den Browser als Parameter für die Tests. Gründe dafür sind:
Der Unterschied, den ich zwischen meiner Code-Struktur und der von Ihnen erwähnten Frage sehe, ist, dass ich für jeden Testfall keine Testklasse habe. Tests werden basierend auf den Features, die ich getestet habe, geteilt und jedes Feature hat eine Klasse. Und diese Klasse wird alle Tests als Methoden halten. Ich benutze testNG, damit diese Methoden parallel aufgerufen werden können. Möglicherweise wird dies nicht Ihre AUT passen.
Wenn Sie die Code-Struktur beibehalten, die Sie in der Frage erwähnen, wird es früher oder später zu einem Alptraum werden. Versuche dich an die Regel zu halten: den gleichen Testcode (einmal geschrieben) für alle Browser (Umgebungen).
Diese Bedingung wird Sie zwingen, zwei Probleme zu lösen:
1) Wie man die Tests für alle ausgewählten Browser ausführt
2) So wenden Sie bestimmte Browser-Problemumgehungen an, ohne den Testcode zu verschmutzen
Eigentlich scheint das Ihre Frage zu sein.
Hier ist, wie ich das erste Problem gelöst habe. Zuerst habe ich alle Umgebungen definiert, die ich testen werde. Ich nenne "Umgebungen" alle Bedingungen, unter denen ich meine Tests durchführen möchte: Browser-Name, Versionsnummer, Betriebssystem usw. Also habe ich, getrennt vom Test-Code, eine Enumeration wie folgt erstellt:
%Vor%Es ist einfach, jederzeit Umgebungen zu ändern und hinzuzufügen. Wie Sie bemerken, verwende ich dies, um die DesiredCapabilities zu erstellen und abzurufen, die später zum Erstellen eines bestimmten WebDrivers verwendet werden.
Um die Tests für alle definierten Umgebungen ausführen zu können, habe ich JUnit's (4.10 in meinem Fall) verwendet org.junit.experimental.theories :
%Vor% Die Tests werden als @Theory
(nicht als @Test
, wie in normalen JUnit-Tests) kommentiert und ein Parameter übergeben. Jeder Test wird dann für alle definierten Werte dieses Parameters ausgeführt, der ein Array von Werten sein sollte, die als @DataPoints
annotiert sind. Außerdem sollten Sie einen Runner verwenden, der sich von org.junit.experimental.theories.Theories
erstreckt. Ich benutze org.junit.rules
, um meine Tests vorzubereiten und dort alle notwendigen Installationen vorzunehmen. Wie Sie sehen können, bekomme ich auch den spezifischen Fähigkeitstreiber durch die Regel. Obwohl Sie den folgenden Code direkt in Ihrem Test verwenden könnten:
Der Punkt ist, dass Sie in der Regel den Code einmal schreiben und ihn für alle Ihre Tests verwenden. Wie bei der Page-Klasse handelt es sich um eine Klasse, in der ich den gesamten Code einfüge, der die Funktionalität des Treibers nutzt (finde ein Element, navigiere usw.). Auf diese Weise bleibt der Testcode sauber und klar und Sie schreiben ihn einmal und verwenden ihn in allen Tests. Also, das ist die Lösung für das erste Problem. (Ich weiß, dass Sie eine ähnliche Sache mit TestNG machen können, aber ich habe es nicht versucht.)
Um das zweite Problem zu lösen, habe ich ein spezielles Paket erstellt, in dem ich den gesamten Code browserspezifischer Problemumgehungen behalte. Es besteht aus einer abstrakten Klasse, z.B. BrowserSpecific, das den gemeinsamen Code enthält, der in einem Browser anders ist (oder einen Bug hat). Im selben Paket habe ich Klassen für jeden Browser, der in Tests verwendet wird, und jeder von ihnen erweitert BrowserSpecific.
So funktioniert es für den von Ihnen erwähnten Chrome-Treiber-Fehler. Ich erstelle eine Methode clickOnButton
in BrowserSpecific mit dem gemeinsamen Code für das betroffene Verhalten:
und dann überschreibe ich diese Methode in der spezifischen Klasse, z. ChromeSpecific, wo ich den Umgehungscode ablege:
%Vor%Wenn ich das spezifische Verhalten eines Browsers berücksichtigen muss, mache ich folgendes:
%Vor%anstelle von:
%Vor%Auf diese Weise kann ich in meinem gemeinsamen Code leicht erkennen, wo die Problemumgehung angewendet wurde, und die Problemumgehungen vom gemeinsamen Code isolieren. Ich finde es leicht zu warten, da die Fehler normalerweise gelöst werden und die Problemumgehungen geändert oder beseitigt werden können.
Ein letztes Wort zum Ausführen der Tests. Wenn Sie Selenium Grid verwenden, sollten Sie die Möglichkeit nutzen, die Tests parallel auszuführen. Denken Sie also daran, diese Funktion für Ihre JUnit-Tests zu konfigurieren (verfügbar ab Version 4.7).
Wir verwenden testng in unserer Organisation und verwenden die Parameteroption, die testng gibt, um die Umgebung anzugeben, d. h. den zu verwendenden Browser, die Maschine, auf der sie ausgeführt wird, und jede andere Konfiguration, die für env config benötigt wird. Der Browsername wird über die XML-Datei gesendet, die steuert, was ausgeführt werden muss und wo. Es wird als globale Variable festgelegt. Was wir als Extra getan haben, ist, dass wir unsere benutzerdefinierten Annotationen haben, die diese globalen Variablen überschreiben können, d. H. Wenn ein Test ganz spezifisch nur auf Chrome und keinem anderen Browser ausgeführt wird, dann geben wir dasselbe in der benutzerdefinierten Annotation an. Also, egal, auch wenn der Parameter auf FF ausgeführt wird, wenn er mit Chrom annotiert ist, würde er immer auf Chrom laufen.
Ich glaube irgendwie, dass es keine gute Idee ist, für jeden Browser eine Klasse zu erstellen. Stellen Sie sich vor, der Fluss ändert sich oder es gibt ein bisschen hier und da und Sie haben 3 Klassen statt einer zu ändern. Und wenn die Anzahl der Browser zunimmt, dann eine weitere Klasse.
Ich würde vorschlagen, Code zu haben, der browserspezifisch ist, um extrahiert zu werden. Wenn das Klickverhalten also browserspezifisch ist, überschreiben Sie es, um entsprechende Überprüfungen oder Fehlerhandhabungen basierend auf Browsern durchzuführen.
Ich mache es so, aber bedenke, dass dies reiner WebDriver ist ohne das Grid oder RC:
%Vor%Nun, mit JUnit 4.11+ muss Ihre Parameterdatei in etwa so aussehen:
%Vor%Verwenden Sie dann eine einzelne .CSV-parametrisierte Testklasse (mit der Sie mehrere Browsertypen starten möchten) in der @Before-Methode mit Anmerkungen:
Natürlich sagt meine Antwort nicht, wie man mit den Parametern umgeht: Ich lasse das für Sie, um herauszufinden.
Tags und Links selenium selenium-webdriver webdriver selenium-grid