So schreiben und führen Sie Unit-Tests in Python mit PyTest aus
Wenn Sie Code in Python schreiben, ist es wichtig sicherzustellen, dass Ihr Code wie erwartet funktioniert. Eine der besten Möglichkeiten hierfür sind Unit-Tests, 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?
Unit-Tests 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.
Unit-Tests können für verschiedene Teile Ihres Codes geschrieben werden, beispielsweise 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 vereinfacht.
Es ist einfach zu bedienen und verfügt über viele nützliche Funktionen wie:
- Es ermöglicht Ihnen, einfache und klare Testfälle zu schreiben.
- Es bietet erweiterte Funktionen wie Vorrichtungen, parametrisierte Tests und Plugins.
- Es funktioniert gut mit anderen Testtools und Bibliotheken.
- Es generiert leicht lesbare Testergebnisse und Berichte.
PyTest unter Linux einrichten
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 namens pip installieren.
pip install pytest
Sobald PyTest installiert ist, können Sie mit dem Schreiben von Tests beginnen!
Schreiben Sie Ihren ersten Test mit PyTest
Beginnen wir mit dem Schreiben einer einfachen Funktion und schreiben dann einen Test dafür.
Schritt 1: Schreiben Sie eine einfache Funktion
Erstellen wir zunächst 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
Dies ist eine einfache Funktion, die zwei Zahlen a und b nimmt, sie addiert und das Ergebnis zurückgibt.
Schritt 2: Schreiben Sie einen Test für die Funktion
Schreiben wir nun einen Test für die Add-Funktion. In PyTest werden Tests in separate Dateien geschrieben, die normalerweise test_*.py
heißen, 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 Funktion
add
aus der Dateiadd.py
. - Wir definieren eine Testfunktion namens
test_add_numbers()
. In PyTest sollte eine Testfunktion mit dem Worttest_
beginnen. - Innerhalb der Testfunktion verwenden wir die Anweisung
assert
, um zu prüfen, ob das Ergebnis des Aufrufs der Funktionadd
mit dem erwarteten Wert übereinstimmt. Wenn die Bedingung in derassert
-AnweisungTrue
ist, ist der Test erfolgreich; andernfalls schlägt es fehl.
Schritt 3: Führen Sie den Test durch
Um den Test auszuführen, öffnen Sie Ihr Terminal, navigieren Sie zu dem Verzeichnis, in dem sich Ihre Datei test_add.py
befindet, und führen Sie dann den folgenden Befehl aus:
pytest
PyTest findet automatisch alle Testdateien (die mit test_
beginnen) und führt die darin enthaltenen Tests aus. Wenn alles korrekt funktioniert, sollten Sie eine Ausgabe wie diese sehen:
Der Punkt (.)
zeigt an, dass der Test bestanden wurde. Bei Problemen würde PyTest eine Fehlermeldung anzeigen.
Fortgeschrittenere Tests schreiben
Nachdem wir nun wissen, wie man einen einfachen Test schreibt und ausführt, wollen wir uns einige erweiterte Funktionen von PyTest ansehen.
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 Funktion divide
:
# divide.py
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
Schreiben wir nun einen Test für diese Funktion, der prü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 prüfen, ob einValueError
ausgelöst wird, wenn wir die Divisionsfunktion mit Null als zweitem Argument aufrufen.
Führen Sie die Tests erneut mit dem Befehl pytest aus. Wenn alles korrekt funktioniert, sollten Sie diese Ausgabe sehen:
Verwendung von Fixtures für die Einrichtung und Bereinigung
In einigen Fällen müssen Sie möglicherweise bestimmte Bedingungen einrichten, bevor Sie Ihre Tests ausführen, oder nach Abschluss der Tests Aufräumarbeiten durchführen. PyTest bietet Vorrichtungen, um dies zu bewältigen.
Eine Vorrichtung ist eine Funktion, mit der Sie Bedingungen für Ihre Tests einrichten oder entfernen können. Fixtures werden häufig zum Erstellen von Objekten oder zum Herstellen einer Verbindung zu Datenbanken verwendet, die für die Tests benötigt werden.
Hier ist ein Beispiel für die Verwendung eines Fixtures zum Einrichten eines temporären Verzeichnisses zum Testen von Dateivorgängen:
# 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 eine Vorrichtung namens
temporary_directory
, die vor dem Test ein temporäres Verzeichnis erstellt und es anschließend löscht. - Die Testfunktion
test_create_file()
verwendet diese Vorrichtung, um eine Datei im temporären Verzeichnis zu erstellen und prüft, ob die Datei vorhanden ist.
Führen Sie die Tests erneut mit dem Befehl pytest aus. PyTest erkennt und verwendet das Gerät automatisch.
Parametrisieren Sie Ihre Tests mit Pytest
Manchmal möchten Sie denselben Test mit unterschiedlichen Eingaben ausführen. PyTest ermöglicht Ihnen dies ganz einfach mithilfe von Parametrisieren.
Nehmen wir an, wir möchten unsere Funktion add
mit mehreren Zahlenpaaren testen. Anstatt für jedes Paar separate Testfunktionen 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 Dekorator
pytest.mark.parametrize
, um mehrere Sätze von Eingaben zu definieren (a
,b
undexpected
). ). - Die Test-
Funktion test_add_numbers()
wird für jeden Eingabesatz einmal ausgeführt.
Führen Sie die Tests erneut mit dem Befehl pytest aus, der den Test viermal ausführt, einmal für jeden Eingabesatz.
Abschluss
In diesem Artikel haben wir gelernt, wie Sie mit PyTest effektive Unit-Tests 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, während Sie auf Ihrer Python-Reise vorankommen.