Hopp til innhold

Unit-Tests und Validierung

Skip to content

Dies ist ein maschinell übersetzter Text, der Fehler enthalten kann!

Unit-Testing und Validierung

Da wir nun Klassen erstellt und an der Validierung gearbeitet haben, liegt eine gute Grundlage für den Beginn des Testens vor. Das Testen ist ein wichtiger Teil des Entwicklungsprozesses und hilft uns dabei sicherzustellen, dass unser Code wie erwartet funktioniert.

Denn wie können wir sicherstellen, dass der Code so funktioniert, wie er soll, wenn wir ihn nicht testen?

Was ist Unit-Testing?

Unit-Testing ist eine Methode zum automatischen und systematischen Testen kleiner Teile unseres Codes. In Python verwenden wir ein Modul namens pytest, um Tests zu schreiben und auszuführen. Eine „Einheit“ (Unit) ist der kleinste testbare Teil einer Anwendung, oft eine einzelne Funktion oder Methode. Wenn wir pytest verwenden, ist es wichtig, dass wir die richtigen Namenskonventionen einhalten, damit pytest unsere Tests finden kann, wie z. B. die Benennung von Testdateien mit einem Präfix von test_ und von Testfunktionen ebenfalls mit dem Präfix test_.

Beispiel für einen Unit-Test:

The provided Python code contains no comments (only a function definition and an assertion). Therefore, it remains unchanged as per the requirement to preserve executable code exactly.

def test_add():
    assert 0.3 + 0.3 + 0.3 == 0.9

Wird ausgeführt, indem in der Terminal pytest eingegeben wird.

Trivia

Der obige Code wird fehlschlagen, da in Python aus .3+.3+.3 der Wert 0.8999999999 entsteht!

Easy Aufgabe 1 – Installation von pytest

Installiere pytest in deiner virtuellen Umgebung. Dies erfolgt durch die Ausführung des folgenden Befehls im Terminal:

pip install pytest

Easy Aufgabe 2 – Erstellen eines Tests

Erstelle eine neue Datei in deinem Projektordner mit dem Namen test_data.py. In dieser Datei sollst du einen Test für die Klasse Person, die du im letzten Modul erstellt hast, schreiben. Der Test soll prüfen, ob eine Person mit gültigen Werten erstellt werden kann.

Beispiel dafür, wie der Test aussehen könnte:

from main import Person

def test_person_working():
    bob_kaare = Person(name="Bob Kåre",
                       eye_color=EyeColor.BLUE,
                       phone_number=PhoneNumber("12345678"),
                       email=Email("bob_kaare@example.com"))
    assert bob_kaare.name == "Bob Kåre"
    assert bob_kaare.eye_color == EyeColor.BLUE

Diese Art von Test wird als „Happy Path“-Test bezeichnet, da wir testen, dass alles so funktioniert, wie es soll, wenn wir gültige Werte übergeben, und ist nicht besonders nützlich.

Medium Aufgabe 3 – Validierung testen

Erstelle mehrere Tests in test_person.py, die sicherstellen, dass die Validierung von Email und PhoneNumber wie erwartet funktioniert. Teste sowohl gültige als auch ungültige Werte. Hierbei musst du eine Funktion aus pytest namens raises verwenden, die überprüft, ob ein bestimmter Fehler ausgelöst wird.

import pytest

def test_exception():
    with pytest.raises(KeyError):
        my_dict = {"a": 1, "b": 2}
        value = my_dict["c"]  # Dies wird eine KeyError auslösen

Tip

Sie können so viele Funktionen erstellen, wie Sie möchten, solange der Funktionsname mit test_ beginnt.

Lösung: Beispiel für einen Test einer ungültigen E-Mail-Adresse
from main import Email

import pytest

def test_invalid_email():
    with pytest.raises(ValueError):
        email = Email("not-an-email")

Warum das tun?

Indem wir gute Tests für unseren Code haben, können wir sicherstellen, dass dieser wie vorgesehen funktioniert und wir leicht feststellen können, ob etwas schiefgelaufen ist, wenn wir Änderungen am Code vornehmen. Dies ist besonders wichtig bei größeren Projekten, in denen viele Entwickler zusammenarbeiten und es leicht zu Fehlern kommt.

Video: Warum Tests den Code vor neuen Fehlern schützen

Das Video erklärt, warum Testing wichtig ist und wie automatische Tests Fehler nach Änderungen im Code aufdecken können.

Durch die Verwendung von Software wie Jest oder Selenium beispielsweise kann man Websites automatisch testen und damit sicherstellen, dass alles nach jeder Änderung am Code funktioniert, wie es soll. Wir möchten schließlich gerne wissen, ob „Benutzerregistrierung“, „Zahlung“ und „Anmeldung“ ordnungsgemäß funktionieren, nicht wahr?

Denken Sie über die folgenden Szenarien nach

Was passiert (oder passieren soll), wenn…:

  • Ein Benutzer versucht, sich mit einer E-Mail-Adresse zu registrieren, die bereits verwendet wird?
  • Ein Benutzer hat ein Geburtsdatum in der Zukunft?
  • Ein Benutzer gibt den Namen „jOHN dOE“ ein?

A software tester walks into a bar...

Hard Aufgabe 4 - Automatisiertes Testen (CI)

Wenn wir Code auf GitHub veröffentlichen, können wir etwas namens GitHub Actions einrichten, das unsere Tests automatisch jedes Mal ausführt, wenn wir eine Änderung am Code vornehmen. Dies wird als Continuous Integration (CI) bezeichnet und hilft uns sicherzustellen, dass unser Code immer wie erwartet funktioniert.

Erstellen Sie eine Datei in Ihrem Projektordner mit dem Namen .github/workflows/pytest.yml. Fügen Sie in dieser Datei den folgenden Code hinzu:

name: Pytest

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.11'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install pytest
        # Installiere alle anderen Abhängigkeiten, die dein Projekt benötigt
        pip install -r requirements.txt
    - name: Run tests with pytest
      run: pytest

Wenn Sie es korrekt eingerichtet haben, sehen Sie jetzt einen neuen Tab in Ihrem GitHub-Repository namens „Actions“. Hier können Sie verfolgen, dass Ihre Tests jedes Mal automatisch ausgeführt werden, wenn Sie eine Änderung am Code vornehmen, und Sie erhalten Benachrichtigungen, falls einer der Tests fehlschlägt (rotes Kreuz und per E-Mail).

Hinweis zur Dateistruktur

Deine Dateistruktur bestimmt, ob GitHub Actions funktioniert oder nicht. Stelle sicher, dass der Ordner .github im Stammverzeichnis deines Projekts liegt und ebenso ein tests-Ordner, in dem sich deine Testdateien befinden.

Du kannst gegebenenfalls die Datei pytest.yml ändern, um auf den richtigen Ordner zu verweisen.

Solche Actions-Dateien können auch verwendet werden, um Ihren Code auf mehreren Versionen von Python oder Betriebssystemen zu testen. Sie können auch verwendet werden, um Ihre Software automatisch zu erstellen und zu veröffentlichen, z. B. eine Website zu veröffentlichen oder eine App im App Store oder Google Play zu aktualisieren.

Code Coverage

Es gibt auch etwas namens „Code Coverage“, das dir helfen kann zu sehen, wie viel von deinem Code tatsächlich getestet wird. Dies kann nützlich sein, um festzustellen, ob du genügend Tests hast oder ob es Teile deines Codes gibt, die überhaupt nicht getestet werden.

Einige Arbeitgeber verlangen, dass ein bestimmter Prozentsatz deines Codes durch Tests abgedeckt ist, bevor du ihn bereitstellen kannst, um sicherzustellen, dass der Code robust und funktionsfähig ist.

Unit Test Meme