Pytest ist ein Testframework um einzelne Funktionen eines Programms automatisiert zu testen.
Das fortlaufende Testen deiner Programmfunktionen ist ein wichtiger Schritt, um die korrekte Verarbeitung sicherzustellen. Jeder neu geschriebene oder veränderte Code kann Fehler enthalten. Anstatt jedesmal manuell alle Tests durchzuführen, wollen wir die Tests automatisieren. Dies bedeutet zwar einen zusätzlichen Aufwand, um die Testfunktionen zu schreiben. Diese Zeit sparen wir aber wieder ein, wenn wir diese Tests immer und immer wieder nutzen können.
Für die Programmieraufgaben in den Programmiermodulen sind die Testfunktionen bereits vorgegeben. Daher konzentrieren wir uns darauf, diese Tests und deren Resultate zu verstehen.
Die einzelnen Unit Tests werden als Funktionen in Python programmiert. Zum Beispiel:
def test_normal(): result = factorial(7) assert result == 5040
test
beginnen. Andernfalls erkennt pytest
die Funktion nicht.factorial
) mit den Testdaten auf.assert
vergleicht das tatsächliche Resultat mit dem erwarteten Resultat.
Der Befehl assert
ist eine spezielle Bedingung, die wir zum Testen und Debuggen von Code verwenden.
Falls die Bedingung erfüllt ist, wird true
zurück gegeben.
Sonst wird eine AssertionError
-Exception geworfen.
Wir könnten das gleiche Resultat auch mit if
/else
erreichen:
assert | if / else |
---|---|
assert result == 5040 | if result == 5040: return true else: raise AssertionError |
Während der Entwicklung führe ich jede Testfunktion einzeln aus. Dadurch werde ich nicht von einer grossen Anzahl an Fehlermeldungen auf einmal überwältigt.
Um eine einzelne Testfunktion auszuführen, kann ich …
pytest -k TESTFUNKTION
eingeben. Bevor ich einen Push ins GitHub-Repository mache, führe ich jeweils alle Testfunktionen aus. Dadurch stelle ich sicher, dass meine Änderungen keine unerwarteten Auswirkungen auf andere Programmteile haben.
Falls ein Test nicht erfolgreich war, musst du die Ausgaben analysieren.
E AssertionError: assert '7\n' == '0\n' E - 0 E + 7
Hier wurde der Test ausgeführt, aber das Resultat entspricht nicht den Erwartungen.
Übrigens: Das '\n' steht für einen Zeilenumbruch.
divider_test.py::test_2 FAILED [100%] divider_test.py:11 (test_2) monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x000001B8EC7B08E0> capsys = <_pytest.capture.CaptureFixture object at 0x000001B8EC7B0AF0> def test_2(monkeypatch, capsys): inputs = iter(['0', '7']) monkeypatch.setattr('builtins.input', lambda _: next(inputs)) > divider.main() divider_test.py:15: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def main(): """ Ermittelt den grössten gemeinsamen Teiler von zwei Ganzzahlen :return: None """ first_number = int(input("Gib die erste Ganzzahl ein > ")) second_number = int(input("Gib die zweite Ganzzahl ein > ")) while second_number != 0: > foo = second_number / first_number E ZeroDivisionError: division by zero divider.py:9: ZeroDivisionError
Bei diesem Beispiel ist das Programm abgestürzt.
Eine wichtige Information steckt in der letzten Zeile: divider.py:9: ZeroDivisionError
:
divider.py
hat den Absturz verursacht.ZeroDivisionError
wurde ausgelöst.In einem solchen Fall muss du die Programmlogik genau studieren und evtl. den Test mit Hilfe des Debuggers schrittweise durchführen.