Wie man Unit-Tests in Python mit PyTest schreibt und ausführt
Wenn Sie Code in Python schreiben, ist es wichtig sicherzustellen, dass Ihr Code wie erwartet funktioniert. Eine der besten Möglichkeiten, dies zu tun, ist die Verwendung von Komponententests, mit denen Sie überprüfen können, ob kleine Teile (oder Einheiten) Ihres Codes ordnungsgemäß funktionieren.
In diesem Artikel erfahren Sie, wie Sie mit PyTest, einem der beliebtesten Test-Frameworks für Python, effektive Unit-Tests in Python schreiben und ausführen.
Was sind Unit-Tests?
Komponententests sind kleine, einfache Tests, die sich auf die Überprüfung einer einzelnen Funktion oder eines kleinen Codeabschnitts konzentrieren. Sie tragen dazu bei, dass Ihr Code wie erwartet funktioniert und Fehler frühzeitig erkannt werden können.
Komponententests können für verschiedene Teile des Codes geschrieben werden, z. B. für Funktionen, Methoden und sogar Klassen. Durch das Schreiben von Komponententests können Sie Ihren Code testen, ohne das gesamte Programm auszuführen.
Warum PyTest verwenden?
PyTest ist ein beliebtes Testframework für Python, das das Schreiben und Ausführen von Tests erleichtert.
Es ist einfach zu bedienen und verfügt über viele nützliche Funktionen wie:
- Es ermöglicht Ihnen, einfache und übersichtliche Testfälle zu schreiben.
- Es bietet erweiterte Funktionen wie Geräte, parametrisierte Tests und Plugins.
- Es funktioniert gut mit anderen Testtools und Bibliotheken.
- Es generiert leicht lesbare Testergebnisse und Berichte.
Einrichten von PyTest unter Linux
Bevor wir mit dem Schreiben von Tests beginnen, müssen wir PyTest installieren. Wenn Sie PyTest nicht installiert haben, können Sie es mit dem Python-Paketmanager pip installieren.
pip install pytest
Sobald PyTest installiert ist, können Sie mit dem Schreiben von Tests beginnen!
Schreiben Ihres ersten Tests mit PyTest
Beginnen wir damit, eine einfache Funktion zu schreiben und dann einen Test dafür zu schreiben.
Schritt 1: Schreiben einer einfachen Funktion
Zuerst erstellen wir eine Python-Funktion, die wir testen möchten. Nehmen wir an, wir haben eine Funktion, die zwei Zahlen addiert:
# add.py
def add(a, b):
return a + b
Dabei handelt es sich um eine einfache Funktion, die zwei Zahlen a und b nimmt, sie addiert und das Ergebnis zurückgibt.
Schritt 2: Schreiben eines Tests für die Funktion
Lassen Sie uns nun einen Test für die Add-Funktion schreiben. In PyTest werden Tests in separate Dateien geschrieben, die in der Regel test_*.py benannt sind, um die Identifizierung von Testdateien zu erleichtern.
Erstellen Sie eine neue Datei mit dem Namen test_add.py, und schreiben Sie den folgenden Testcode:
# test_add.py
from add import add
def test_add_numbers():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
Erklärung des obigen Codes:
- Wir importieren die
Add-Funktionaus deradd.pyDatei. - Wir definieren eine Testfunktion namens
test_add_numbers().In PyTest sollte eine Testfunktion mit dem Worttest_beginnen. - Innerhalb der Testfunktion verwenden wir die
assert-Anweisung, um zu überprüfen, ob das Ergebnis des Aufrufs deradd-Funktionmit dem erwarteten Wert übereinstimmt. Wenn die Bedingung in derassert-AnweisungTrueist, ist der Test erfolgreich. Andernfalls schlägt es fehl.
Schritt 3: Ausführen des Tests
Um den Test auszuführen, öffnen Sie Ihr Terminal, navigieren Sie zu dem Verzeichnis, in dem sich Ihre test_add.py Datei befindet, und führen Sie dann den folgenden Befehl aus:
pytest
PyTest findet automatisch alle Testdateien (diejenigen, die mit test_ beginnen) und führt die darin enthaltenen Tests aus. Wenn alles ordnungsgemäß funktioniert, sollte eine Ausgabe wie diese angezeigt werden:
Der Punkt (.) gibt an, dass der Test erfolgreich war. Wenn es Probleme gab, zeigte PyTest eine Fehlermeldung an.
Schreiben von komplexeren Tests
Nachdem wir nun wissen, wie man einen grundlegenden Test schreibt und ausführt, lassen Sie uns einige fortgeschrittenere Funktionen von PyTest untersuchen.
Testen auf erwartete Ausnahmen
Manchmal möchten Sie testen, ob Ihr Code die richtigen Ausnahmen auslöst, wenn etwas schief geht. Sie können dies mit der Funktion pytest.raises() tun.
Nehmen wir an, wir möchten eine Funktion testen, die zwei Zahlen dividiert. Wir möchten eine Ausnahme auslösen, wenn die zweite Zahl Null ist (um Fehler bei der Division durch Null zu vermeiden).
Hier ist die Divide-Funktion:
# divide.py
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
Lassen Sie uns nun einen Test für diese Funktion schreiben, der überprüft, ob der ValueError ausgelöst wird, wenn wir versuchen, durch Null zu dividieren:
# test_divide.py
from divide import divide
import pytest
def test_divide_numbers():
assert divide(10, 2) == 5
assert divide(-10, 2) == -5
assert divide(10, -2) == -5
def test_divide_by_zero():
with pytest.raises(ValueError):
divide(10, 0)
Erklärung des Codes:
- Wir haben eine neue Testfunktion namens
test_divide_by_zero()hinzugefügt. - Innerhalb dieser Funktion verwenden wir
pytest.raises(ValueError),um zu überprüfen, ob einValueErrorausgelöst wird, wenn wir die Divide-Funktion mit Null als zweitem Argument aufrufen.
Führen Sie die Tests mit dem Befehl pytest erneut aus. Wenn alles ordnungsgemäß funktioniert, sollte diese Ausgabe angezeigt werden:
Verwenden von Fixtures für Setup und Cleanup
In einigen Fällen müssen Sie möglicherweise bestimmte Bedingungen einrichten, bevor Sie die Tests ausführen, oder die Bereinigung nach Abschluss der Tests durchführen. PyTest stellt Halterungen bereit, um dies zu handhaben.
Eine Halterung ist eine Funktion, mit der Sie Bedingungen für Ihre Tests einrichten oder entfernen können. Fixtures werden häufig verwendet, um Objekte zu erstellen oder eine Verbindung zu Datenbanken herzustellen, die für die Tests benötigt werden.
Hier ist ein Beispiel für die Verwendung eines Fixtures, um ein temporäres Verzeichnis zum Testen von Dateioperationen einzurichten:
# test_file_operations.py
import pytest
import os
@pytest.fixture
def temporary_directory():
temp_dir = "temp_dir"
os.mkdir(temp_dir)
yield temp_dir # This is where the test will run
os.rmdir(temp_dir) # Cleanup after the test
def test_create_file(temporary_directory):
file_path = os.path.join(temporary_directory, "test_file.txt")
with open(file_path, "w") as f:
f.write("Hello, world!")
assert os.path.exists(file_path)
Erklärung des Codes:
- Wir definieren ein Fixture namens
temporary_directory,das vor dem Test ein temporäres Verzeichnis erstellt und es danach löscht. - Die Testfunktion
test_create_file()verwendet dieses Fixture, um eine Datei im temporären Verzeichnis zu erstellen und prüft, ob die Datei existiert.
Führen Sie die Tests mit dem Befehl pytest erneut aus. PyTest erkennt und verwendet die Leuchte automatisch.
Parametrisieren Sie Ihre Tests mit Pytest
Manchmal möchten Sie denselben Test mit unterschiedlichen Eingaben ausführen. PyTest ermöglicht es Ihnen, dies einfach mit Parametrize zu tun.
Nehmen wir an, wir möchten unsere Add-Funktion mit mehreren Zahlenpaaren testen. Anstatt separate Testfunktionen für jedes Paar zu schreiben, können wir pytest.mark.parametrize verwenden, um denselben Test mit unterschiedlichen Eingaben auszuführen.
# test_add.py
import pytest
from add import add
@pytest.mark.parametrize("a, b, expected", [
(2, 3, 5),
(-1, 1, 0),
(0, 0, 0),
(100, 200, 300)
])
def test_add_numbers(a, b, expected):
assert add(a, b) == expected
Erklärung des Codes:
- Wir verwenden den
pytest.mark.parametrize-Dekorator, um mehrere Sätze von Eingaben (a,bunderwartet)zu definieren. - Die
Testfunktion test_add_numbers()wird einmal für jeden Satz von Eingaben ausgeführt.
Führen Sie die Tests erneut mit dem Befehl pytest aus, wodurch der Test viermal ausgeführt wird, einmal für jede Gruppe von Eingaben.
Schlussfolgerung
In diesem Artikel haben wir gelernt, wie Sie mithilfe von PyTest effektive Komponententests in Python schreiben und ausführen, um Fehler frühzeitig zu erkennen und sicherzustellen, dass Ihr Code wie erwartet funktioniert.
PyTest macht es einfach, diese Tests zu schreiben und auszuführen, und mit seinen leistungsstarken Funktionen können Sie komplexere Testanforderungen bewältigen, wenn Sie auf Ihrer Python-Reise wachsen.

