Python Pytest: Aus welchen Gründen sollte man seinen Code testen?
In einem früheren Artikel haben wir gesehen, warum Unit-Tests für die Qualität und das Funktionieren eines Codes von grundlegender Bedeutung sind.
Zur Erinnerung: Mit Unit-Tests können verschiedene Teile eines Codes isoliert getestet werden, im Gegensatz zu Integrationstests, die das Funktionieren des Codes als Ganzes überprüfen. Sie unterscheiden sich auch von Funktionstests (functional testing), die das Funktionieren einer bestimmten Funktion sicherstellen.
Warum sollte man den Python Pytest Framework verwenden, um seinen Code zu testen?
Um die Automatisierung von Unit-Tests zu erleichtern, kann man Testing-Frameworks verwenden, die das Schreiben von Tests standardisieren, fehlgeschlagene Tests schnell identifizieren und die Wartung erleichtern.
In Python gibt es verschiedene Test-Frameworks, von denen die bekanntesten Unittest und Pytest sind. Heute konzentrieren wir uns auf die Implementierung von Unit-Tests mit Pytest, das etwas einfacher zu erlernen ist.
Wie verwendet man Python Pytest ?
Als Erstes musst du die Pytest-Bibliothek mit dem Befehl pip install pytest installieren.
In einem Ordner erstellen wir die Datei student.py. Darin erstellen wir eine Klasse Student, die es uns ermöglicht, Schülerinstanzen zu erstellen, ihre Noten zu speichern und ihren Durchschnitt zu berechnen.
Im selben Ordner erstellen wir eine Testdatei student_test.py. Die Namen der Testdateien sollten im Format „test_dateiname.py“ oder „test_dateiname.py“ geschrieben werden. In der Datei muss jeder Test durch eine Funktion mit dem Präfix „test“ definiert werden.
Mit assert statements kannst du überprüfen, ob die Funktion für gegebene Argumente ein korrektes Ergebnis zurückgibt und eine Exception werfen, wenn die Bedingung falsch ist. In unserem Beispiel überprüfen die ersten beiden Funktionen die Eigenschaften (grades, academic average) eines Objekts vom Typ Student bei seiner Instanziierung und dann den Wert des Durchschnitts, nachdem eine Note von 12 hinzugefügt wurde.
Wenn die Testdateien mit dem richtigen Präfix versehen sind, reicht es aus, den Befehl python -m pytest in deinem Terminal auszuführen, um die Tests zu starten. Um einen bestimmten Test zu starten, führe den Befehl python -m pytest Name_der_Datei.py aus.
Nach der Ausführung liefert Python Pytest einen detaillierten Bericht über die Tests.
Die „collected items“ entsprechen der Anzahl der Tests, die durchgeführt werden. Hier wurden alle drei Tests durchgeführt.
Wir ändern vorübergehend unsere Datei student.py so, dass ein Schüler bei seiner Instanziierung standardmäßig eine Note von 10 erhalten hat.
In unserer Datei student_test.py maskieren wir die ersten beiden Testfunktionen, um nur die Funktion test_add_grades zu behalten, und führen dann die Testdatei aus.
Wir stellen fest, dass der Test nicht mehr funktioniert, weil die Änderungen in unserer Datei student.py die Behauptung falsch machen. Mit Pytest können wir also sehen, ob Änderungen an einem Code das erwartete Ergebnis beeinflussen oder nicht.
NB: Wir müssen die init-Funktion von student.py ändern, um bei der Instanziierung wieder eine leere Liste zu erhalten.
Vermeide Wiederholungen mit pytest fixtures.
Im vorherigen Beispiel haben wir in jedem Test ein Objekt vom Typ Student instanziiert. Um zu vermeiden, dass Code, der in mehreren Tests verwendet wird, neu geschrieben werden muss, verfügt Pytest über einen speziellen Dekorator namens fixture, der es ermöglicht, leicht auf die Elemente zuzugreifen, die für die Ausführung eines Tests benötigt werden, wie z. B. Daten.
Um anzugeben, dass eine Funktion eine Fixture ist, musst du den @pytest.fixture-Dekorator verwenden, bevor du sie definierst. Außerdem musst du die Fixture als Argument in den Testfunktionen übergeben, in denen du sie aufrufen willst.
In diesem Beispiel erspart uns die Fixture, dass wir das Schülerobjekt in jedem Test neu instanziieren müssen.
Der Dekorateur parametrize tests zum Testen einer Folge von Anweisungen.
Die Parametrisierung ermöglicht es, denselben Test mit verschiedenen Werten auszuführen. Dazu verwenden wir den Dekorator @pytest.mark.parametrize. Du musst den Namen der zu testenden Argumente und ihren Wert angeben.
Fazit
In diesem Artikel haben wir uns mit der Verwendung von Pytest zum Testen von Code vertraut gemacht.
Als Data Engineer oder Data Scientist ist die Durchführung von Unit-Tests ein notwendiger Schritt, um die Qualität eines Codes zu gewährleisten und Probleme bei der Bereitstellung zu reduzieren.
Es muss jedoch daran erinnert werden, dass dieser Schritt nicht ausreichend ist. Einerseits können bei der Entwicklung einer Machine-Learning-Anwendung einige Elemente durch die Maschen des Netzes fallen. Außerdem können Unit-Tests per Definition nicht die Interaktion zwischen den Einheiten testen.