#Python #Unittest #Selenium #Automation
In diesem Beitrag werden wir uns ansehen, wie man eine Webanwendung in Python Unit-testet, um die Richtigkeit der Funktionalität zu überprüfen. Whoa! Dieser Satz enthält eine Handvoll Jargon: Komponententest, Webanwendung und Funktionstests.
Wir haben uns in einem früheren Beitrag das Testen eines Python-Programms angesehen. Wir empfehlen Ihnen, es durchzugehen, wenn Sie mit Unit-Tests nicht vertraut sind.
Was ist ein Komponententest?
Unit ist der kleinste testbare Teil eines Programms oder einer Anwendung.
Komponententests werden also verwendet, um jede testbare Komponente programmgesteuert zu testen.
Sie können ein Backend-Programm oder ein Frontend-Programm wie eine Webanwendung testen.
Für ein Backend-Programm würden Sie einen Komponententest für jede Funktion oder Methode im Code schreiben, da es sich um logische kleinste Einheiten handelt.
Für ein Frontend identifizieren Sie jedoch verschiedene Funktionen, die Sie überprüfen und Komponententests entsprechend schreiben möchten.
In diesem Beitrag werden wir ein Frontend-Programm, nämlich eine Webanwendung, testen.
Was ist eine Webanwendung?
Jede Anwendung, die in einem Webbrowser wie Chrome, Firefox oder Safari gerendert wird.
Alle Webanwendungen haben eines gemeinsam – sie sind für Endbenutzer sichtbar eine HTML-Seite (Hypertext Markup Language). HTML ist einfach eine Formatierungssprache, um zu beschreiben, wie Dinge organisiert werden sollen. Es ist einfach eine Textdatei.
Browser holen sich diese HTML-Seite und interpretieren die Tags (z. B. HEAD, BODY, HREF, TABLE usw.), um Ihnen eine schöne Seite zu zeigen.
Webanwendungen arbeiten in der Client-Server-Architektur – wobei der Webserver den Inhalt hostet, auf den Sie zugreifen möchten, und der Webbrowser als Client fungiert.
Was ist Funktionstest?
Wie der Name schon sagt, besteht Ihr Ziel beim Schreiben von Funktionstestcode darin, die Funktionalität der Anwendung zu testen. Mit anderen Worten, Sie möchten sicherstellen, dass die Anwendung der funktionalen Spezifikation folgt.
Es gibt andere Arten von Tests wie Leistungstests, Sicherheits- (Penetrations-) Tests und Benutzerakzeptanztests.
Der von Ihnen geschriebene Funktionstestcode kann in einem sogenannten Regressionstest enthalten sein, der regelmäßig ausgeführt wird, um sicherzustellen, dass alte Funktionen nicht aufgrund neuer Entwicklungen beeinträchtigt werden.
Am Ende dieses Beitrags werden Sie den unten genannten vollständigen Code verstehen.
Seien Sie nicht entmutigt, wenn Sie das Gefühl haben, dass dies zu viel ist. Das Ziel dieses Beitrags ist es, dies zu analysieren und Ihnen zu zeigen, wie Sie diesen Code verstehen und dann Ihren eigenen schreiben können!
Das folgende Diagramm zeigt den allgemeinen Ansatz zum automatischen Testen einer Webanwendung (Seite).
Um unsere Tests zu schreiben, verwenden wir ein Testframework namens unittest. Es ist Junit in Java oder Nunit in .Net sehr ähnlich.
Mit unittest können Sie Ihren Initialisierungscode in einer setUp-Funktion gruppieren und Code in einer tearDown-Funktion bereinigen.
Das folgende Diagramm zeigt den allgemeinen Ansatz hinter Unit-Tests.
Wie Sie dem obigen Diagramm entnehmen können, besteht eine Testsuite aus einem oder mehreren Testfällen.
Ein Testfall kann einen oder mehrere Tests enthalten. In diesem Beitrag konzentrieren wir uns auf einen Testfall mit einem Test. Am Ende zeigen wir Ihnen, wie Sie dem gleichen Testfall weitere Tests hinzufügen und eine Testsuite erstellen können.
Wie bereits erwähnt, verfügt jeder Testfall über eine setUp- (am Anfang ausführen) und eine tearDown- (am Ende ausführen) Methode, um die Initialisierung bzw. die Bereinigung durchzuführen.
Der obige Codeausschnitt zeigt die Struktur eines Unit-Testfalls.
Zeile 1: Importieren Sie die erforderlichen Bibliotheken. In unserem Fall verwenden wir Selenium- und Unittest-Bibliotheken.
Zeile 3: Sie erstellen eine Klasse namens MyTestCase , die unittest erweitert.Testfall Klasse. Wir sagen, dass unittest.TestCase ist die übergeordnete Klasse und MyTestCase ist die untergeordnete Klasse.
Zeile 4: Wir fügen unseren Initialisierungscode in die setUp-Methode ein. Sie müssen den genauen Methodennamen verwenden, um unittest mitzuteilen, dass Sie hier Ihren Initialisierungscode hinzufügen. Wenn Sie diesen Testfall ausführen, wird diese Methode zuerst ausgeführt.
Zeile 7: Ein Beispieltest, den wir in den Testfall aufnehmen möchten.
Zeile 10: Ein weiterer Beispieltest, den wir in unserem Testfall haben.
Zeile 16: Wir fügen unseren Bereinigungscode in diese tearDown-Methode ein. Im Gegensatz zur setUp-Methode wird die tearDown-Methode zuletzt ausgeführt.
Die Reihenfolge des Methodenaufrufs lautet also:
setUp > test1 > test2 > … > tearDown
Zeile 20: Dies besagt, dass das Hauptprogramm von diesem Ort aus startet.
Zeile 21: So führen Sie den Testfall aus.
Jetzt ist es Zeit für uns, den eigentlichen Test, den wir machen wollten, in die Hände zu bekommen. Denken Sie daran, dass wir testen möchten, ob das Google-Suchfeld mindestens 5 Ergebnisse für ein bestimmtes Suchbegriff zurückgibt.
Schauen wir uns zuerst die setUp-Methode an:
In diesem Code-Snippet erstellen wir den Chrome-Browser-Treiber.
Sie müssen den Selenium Chrome-Treiber von hier herunterladen, wenn Sie ihn noch nicht haben. Zum Zeitpunkt des Schreibens hat Chrome auch Version 74. Da mein Chrome-Browser Version 73 ist, habe ich Version 73 für diese Übung heruntergeladen.
Zeile 2 und 3 Erstellen Sie die Chrome-Option und lassen Sie Selenium Webdriver wissen, dass wir den Browser beim Ausführen des Tests nicht sichtbar machen möchten.
Wenn Sie diese Option nicht hinzufügen, bleibt Ihr Test an der Stelle hängen, an der der Browser geöffnet wird.
Schauen wir uns nun die tearDown-Methode an:
Wir bereinigen einfach den Treiber, indem wir die Methode quit () aufrufen.
Schließlich ist es an der Zeit, einen Blick auf den Test zu werfen, den wir in diesen Testfall aufnehmen möchten. Denken Sie daran, dass wir können testen (assert), ob die Anzahl der zurückgegebenen Suchergebnisse größer oder gleich 5 ist.
Zeile 1: Die Testmethode beginnt mit dem Wort „test“.
Zeile 3: Laden www.google.com web-Seite in den Treiber (Beachten Sie, dass selbst.treiber wird während der Einrichtungszeit erstellt).
Linie 6: Suchen Sie das Suchfeld nach dem HTML-Elementnamen „q“. Sie müssen die HTML-Seite überprüfen, um dies zu identifizieren.
Zeile 7: Machen Sie das Suchfeld leer, falls Standardwerte vorhanden sind.
Zeile 10: Füllen Sie das Suchfeld mit der Suchzeichenfolge „Automatisiertes Testen“.
Zeile 11: Senden Sie die Suchanfrage an Google.
Zeile 14: XPath zur Identifizierung von Suchergebnisüberschriften.
Zeile 17: Warten Sie 10 Sekunden, bis die Google-Ergebnisseite geladen ist.
Zeile 20: Abrufen aller Suchergebnisüberschriften mithilfe des in Zeile 14 definierten XPath.
Zeilen 25 und 26: Suchergebnisüberschriften sind eigentlich eine Liste und wir durchlaufen sie, um sie auf dem Bildschirm auszugeben. Wir haben diese beiden Zeilen nur zu Demonstrationszwecken hinzugefügt. Normalerweise haben Testskripte keine Druckbildschirme, da niemand auf den Bildschirm starren kann, um eine solche Ausgabe zu sehen, wenn sie automatisiert ist.
Zeile 30: Dies ist die eigentliche Behauptung, die wir machen. assertGreater ist eine in unittest definierte Methode.TestCase-Klasse, mit der wir überprüfen können, ob eine Ausgabe größer als der Wert some ist.
Einheitentest.TestCase bietet uns tatsächlich eine Reihe solcher Methoden, um Gleichheit, größer als, kleiner als usw. zu überprüfen. je nachdem, was Sie behaupten möchten. Die folgende Tabelle zeigt einige der gängigen Assert-Methoden.
Wie zu Beginn gezeigt, können Sie den Testfall schreiben, indem Sie Folgendes in Ihrem Code aufrufen:
unittest.main()
In der Befehlszeile können Sie einfach den Dateinamen eingeben, den Sie zum Speichern des Testfalls verwendet haben.
python google_search_test.py
Es läuft setUp(), dann test_result_count() und schließlich tearDown().
Sie sollten eine Ausgabe ähnlich der folgenden sehen:
Wenn ein Test fehlschlägt, wird die Fehlermeldung zusammen mit der fehlgeschlagenen Testmethode angezeigt.
Das ist Ihr erster erfolgreicher Selenium / Unittest-Testfall. Herzlichen Glückwunsch! Es ist ein wichtiger Meilenstein.
Bonus
Wenn Sie den Dampf haben, würde ich Sie ermutigen, dem Rest zu folgen, um noch tiefer in Selenium / unittest Base Web Application automated Testing einzusteigen.
Angenommen, Sie möchten testen, ob die Überschrift „Google“ entspricht.
Der Testcode sieht wie folgt aus:
def test_header(self):
self.driver.get("http://www.google.com")
self.assertEqual("Google", self.driver.title)
Jetzt sieht unser ganzer Testfall wie folgt aus:
class GoogleSearchTest(unittest.TestCase):
def setUp(self): def test_header(self): def test_result_count(self): def tearDown(self):
if __name__ == "__main__":
unittest.main()
Nehmen wir an, dass die obigen Druckbildschirme auskommentiert sind. Wenn Sie den aktualisierten Testfall ausführen, sollten Sie eine Ausgabe wie folgt erhalten:
test_header (__main__.GoogleSearchTest) ... ok
test_result_count (__main__.GoogleSearchTest) ... ok----------------------------------------------------------------------
Ran 2 tests in 13.799s
OK
Es heißt, dass es zwei Tests durchgeführt hat und beide erfolgreich sind.
Angenommen, ich ändere die assertEqual-Bedingung im ersten Test wie folgt:
self.assertEqual("Microsoft", self.driver.title)
Was denkst du, was hier passieren würde?
Ja, Sie haben es richtig erraten. Der erste Testfall schlägt ebenfalls fehl.Treiber.titel ist gleich Google, nicht Microsoft.
Sie erhalten eine Ausgabe ähnlich der folgenden:
test_header (__main__.GoogleSearchTest) ... FAIL
test_result_count (__main__.GoogleSearchTest) ... ok
====================================================================
FAIL: test_header (__main__.GoogleSearchTest)
--------------------------------------------------------------------
Traceback (most recent call last):
File "google_search_test.py", line 19, in test_header
self.assertEqual("Microsoft", self.driver.title)
AssertionError: 'Microsoft' != 'Google'
- Microsoft
--------------------------------------------------------------------
Ran 2 tests in 14.011s
FAILED (failures=1)
Die obige Ausgabe besagt, dass nur ein Test erfolgreich war und der andere fehlgeschlagen ist.
Wenn Sie Ihre Testfälle zum ersten Mal schreiben, können Situationen wie diese auftreten.
Angenommen, Ihr Testfall ist korrekt, identifizieren Sie Fehler im Code und veranlassen die jeweiligen Entwickler, das Problem zu beheben und erneut zu testen.
Wenn dieser Fehler in einem Regressionstest auftritt, wird dieser Fehler aufgrund einer neuen Softwareentwicklung auf der vorhandenen Codebasis verursacht.
Dies zeigt, dass mit der neuen Codebasis etwas nicht stimmt, das behoben werden muss, um sicherzustellen, dass die alte Funktionalität funktioniert. Auch hier müssen sich die Entwickler darum kümmern.
Wie wäre es mit vielen Testfällen? Angenommen, wir haben TestCase1 und TestCase2 mit jeweils mehreren Tests.
Sie können eine sogenannte Testsuite erstellen und mit einem Testläufer wie folgt ausführen:
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestCase1))
suite.addTest(unittest.makeSuite(TestCase2))
runner = unittest.TextTestRunner()
runner.run(suite)
Der obige Code führt alle Tests in TestCase1 und dann in TestCase2 aus.
Das war’s für heute. Hoffe das hilft.