Programmierpraktikum SoSe 2024, Bachelor Informatik, FU Berlin
ProPra2024 > Testen > Unittests > m_pytest

pytest: Das Profi-Testframework

Idea

Ziel

Ich kann Unittests mit dem Profi-Python-Testframework pytest schreiben und ausführen.

Hintergrund

Für die meisten ernsthaften Anwendungen ist pytest das Testframework der Wahl: Es ist zugleich wesentlich leistungsfähiger als unittest und trotzdem handlicher zu benutzen; eine selten günstige Kombination!

Mit seinen Hunderten von Erweiterungen kann pytest auch sehr spezielle Anforderungen abdecken.

Detailed

Arbeitsschritte

Arbeiten Sie sich mittels der Dokumentation von pytest und bei Bedarf weiteren Quellen mittels der folgenden Aufgaben in das Framework ein.

ptest als Ersatz für unittest

  • 1 Installieren Sie pytest mittels pip install pytest.
  • 1 Legen Sie die Datei pytests/test_pytest.py an als exakte Kopie der Datei unittests/test_unittest.py.
  • 2 Rufen Sie pytest pytests/test_pytest.py auf.
  • 1 Aha, offenbar kann pytest als direkter Ersatz von unittest agieren. Welcher Output gefällt Ihnen besser? Warum?

Schlankere Notation für Tests

  • Lesen Sie auf der Homepage der pytest-Dokumentation die Abschnitte "A quick example" und "Features".
  • 2 Übertragen Sie per Analogieschluss den Code in pytests/test_pytest.py von unittest-Stil nach pytest-Stil: Testklasse wegwerfen; Testmethoden zu einfachen Funktionen machen (ohne Parameter); self.assert... ersetzen durch assert.
    (Für den dritten Test müssen Sie die Dokumentation etwas weiter durchforsten. assertAlmostEqual realisiert man in pytest von Hand, wie in der Doku von unittest angegeben.)
  • 3 Machen Sie einen Commit von pytests/test_pytest.py.
    git -P show HEAD
  • 4 Rufen Sie pytest pytests/test_pytest.py auf.
  • 3 Auch in pytest gibt es natürlich eine Lösung für das, was zuvor @unittest.expectedFailure hieß. Finden Sie sie und probieren Sie sie aus.
Hinweis (nur bei Bedarf): Wie markiert man expected failures?

@pytest.mark.xfail

  • 5 Machen Sie einen Commit von pytests/test_pytest.py.
    git -P show HEAD
  • 6 Rufen Sie pytest pytests/test_pytest.py auf.
  • 7 Rufen Sie pytest -v pytests/test_pytest.py auf.

Tests mit Hilfsausgaben

Eine Eigenschaft von pytest ist extrem hilfreich, sobald es etwas komplizierter wird: pytest verschluckt zunächst alle Bildschirmausgaben, die in Test macht und spuckt sie nur dann aus, wenn der Test fehlschlägt.

Dadurch kann man seine Tests so konzipieren, dass sie allerlei Informationen, die für die Diagnose eines Fehlschlags hilfreich sein könnten, routinemäßig ausgeben. Wenn dann ein Versagen auftritt, hat man es im Nu verstanden. Das ist für Modultests meist nicht nötig, aber für komplexe Integrationstests unbezahlbar.

Ergänzen Sie folgende beiden Tests und verstehen Sie sie:

1
2
3
4
5
6
7
def test_failure1():
    print("lots\nof\nstuff")
    assert False

def test_failure2(self):
    print("still\nmore\nstuff")
    assert False
  • 8 Lassen Sie die Tests laufen.
  • 4 Nun übertragen Sie die beiden Tests in unittest-Manier nach unittests/test_unittest.py.
  • 9 python -m unittest unittests/test_unittest.py
  • 2 Vergleichen Sie die Ausgaben der beiden Kommandos. Was ist Ihr Eindruck? Fallen Ihnen noch wichtige Gründe ein, unittest zu benutzen?
Trace

Abgabe

Geben Sie den Quellcode ab, wie er am Ende der Aufgabe vorliegt.

Geben Sie ein Kommandoprotokoll ab, das genau nur die Eingaben und Ausgaben der obigen Kommandos 1, 2, … enthält. Entfernen Sie vor Abgabe eventuelle Fehlversuche und sonstige zusätzliche Kommandos aus dem Protokoll.

Geben Sie ein Markdown-Dokument ab mit knappen Antworten zu den oben gestellten Fragen 1, 2, … Geben Sie diese Marker mit an.
Geben Sie ggf. Beispiele oder benutzte Quellen an.