Python lernen · optional · nicht nötig fürs Spiel
Im MUD: dein Sicherheitsnetz, wenn du am Spielcode arbeitest

Python lernen · 13.09.2026

Python lernen: Tests

Optional · nicht nötig, um zu spielen: Mit assert und unittest beweist dein Code selbst, dass er das tut, was er verspricht.

Eine kleine Änderung kann großes Unglück anrichten: Du verbesserst an nimm im Mini-Abenteuer eine Zeile — und drei Tage später merkt jemand, dass Gegenstände still aus dem Inventar verschwinden. Der Code läuft, keine Fehlermeldung, aber das Ergebnis ist kaputt. Dagegen hilft nur eins: Tests — kleine Prüfprogramme, die automatisch beweisen, dass dein Code das tut, was er verspricht.

Warum gerade in einem MUD?

Ein Spiel stellt dieselben Fragen tausendmal: Hat der Held Gold? Ist die Tür zu, ohne dass ein Schlüssel im Inventar liegt? Stirbt das Monster bei 0 HP? Jede dieser Fragen lässt sich als Behauptung schreiben — auf Englisch assertion, auf Deutsch: „Ich behaupte, dass das stimmt — beweise es.“

assert — die Ein-Satz-Prüfung

assert 2 + 2 == 4          # läuft durch: stimmt
assert "Schlüssel" in ["Schlüssel"]
assert 1 > 2, "Mathe kaputt?"   # AssertionError: Mathe kaputt?

Stimmt die Bedingung, passiert nichts. Stimmt sie nicht, wirft Python einen AssertionError — mit deiner Meldung, wenn du eine angibst. Ein Test ist also nichts weiter als eine Reihe von Behauptungen über deinen Code.

Eine Funktion und ihr Test

Aus dem Mini-Abenteuer kennen wir das Aufheben von Gegenständen. Als Funktion — damit sie sich testen lässt:

def nimm(inventar, raum_items, name):
    if name not in raum_items:
        return False
    raum_items.remove(name)
    inventar.append(name)
    return True

def test_nimm_schluessel():
    inventar = []
    boden = ["schluessel", "fackel"]
    ok = nimm(inventar, boden, "schluessel")
    assert ok is True
    assert "schluessel" in inventar
    assert "schluessel" not in boden

test_nimm_schluessel()
print("ok")

Läuft alles durch, erscheint nur ok. Und jetzt der eigentliche Trick: ein absichtlich scheiternder Test — du suchst „drache“, das nicht am Boden liegt, und erwartest trotzdem Erfolg:

def test_nimm_unbekanntes_item():
    inventar = []
    boden = ["schluessel", "fackel"]
    ok = nimm(inventar, boden, "drache")
    assert ok is True    # schlägt fehl: nimm gibt False zurück

test_nimm_unbekanntes_item()

Der AssertionError zeigt dir Zeile und Ursache — du hast eine falsche Annahme gefunden, bevor ein Spieler sie findet. Genau das ist der Nutzen: Tests sterben zuerst, damit der Code es später nicht tut.

Auch die Tür gehört getestet

Aus dem Mini-Abenteuer: Die Kammer bleibt zu, ohne Schlüssel. Als Funktion formuliert, ist das ein Zwei-Zeilen-Test:

def kann_tuer_oeffnen(inventar):
    return "Schlüssel" in inventar

def test_tuer_zu_ohne_schluessel():
    assert kann_tuer_oeffnen([]) is False
    assert kann_tuer_oeffnen(["Schlüssel"]) is True

test_tuer_zu_ohne_schluessel()
print("Tür-Logik ok")

unittest — eingebaut, kein pip

Wenn es mehr Tests werden, schreibst du sie in eine eigene Datei test_nimm.py und lässt Python alle auf einmal laufen. unittest gehört zur Standardbibliothek — nichts installieren. Lokal: python3 test_nimm.py

import unittest

from kampflogik import nimm

class TestNimm(unittest.TestCase):
    def test_nimmt_item(self):
        inventar, boden = [], ["schlüssel"]
        self.assertTrue(nimm(inventar, boden, "schlüssel"))
        self.assertEqual(inventar, ["schlüssel"])

if __name__ == "__main__":
    unittest.main()

Die Ausgabe: Ran 1 test — OK. Später, wenn du lokal arbeitest, schauen viele Entwickler auf pytest — dasselbe Prinzip, weniger Schreibarbeit. Für den Anfang reicht unittest vollkommen, und im Online-Interpreter bleiben wir bei den schlichten assert-Tests von oben.

So übst du das

  • Erst brechen, dann fixen: Nimm eine Funktion, die du vertraust, und finde eine Eingabe, die sie kippen lässt.
  • Sicherheitsnetz bauen: Bevor du etwas an nimm änderst, schreib die Tests dafür — dann misst du die Änderung, statt sie zu hoffen.
  • Falkenmoor-Gedanken: Formuliere drei Behauptungen aus dem Spiel als asserts — Tür, Gold, HP.
  • Später automatisch: Wenn du lokal an Falkenmoor arbeitest, laufen solche Tests bei jedem Start mit — pytest macht daraus einen Einzeiler.

Übungen

Übung 1 — Die erste Behauptung

Schreibe eine Funktion ist_gerade(n) und teste sie mit zwei asserts — eine gerade und eine ungerade Zahl.

Musterlösung zeigen
def ist_gerade(n):
    return n % 2 == 0

assert ist_gerade(4) is True
assert ist_gerade(7) is False
print("beide Behauptungen stimmen")

Übung 2 — Der Scheiter-Test

Diese Testfunktion erwartet, dass nimm auch unbekannte Items einpackt. Führe sie aus, lies den AssertionError — und korrigiere die Erwartung (ein Test darf auch falsch liegen!).

Musterlösung zeigen
def nimm(inventar, raum_items, name):
    if name not in raum_items:
        return False
    raum_items.remove(name)
    inventar.append(name)
    return True

def test_nimm_drache():
    inventar = []
    boden = ["schlüssel"]
    ok = nimm(inventar, boden, "drache")
    assert ok is True

test_nimm_drache()
print("ok")   # schlägt fehl — mit Recht

Übung 3 — Tür-Logik

Schreibe kann_tuer_oeffnen(inventar) und prüfe beide Fälle mit asserts.

Musterlösung zeigen
def kann_tuer_oeffnen(inventar):
    return "Schlüssel" in inventar

assert kann_tuer_oeffnen([]) is False
assert kann_tuer_oeffnen(["Schlüssel"]) is True
print("Tür-Logik ok")

Übung 4 — unittest-Datei (lokal)

Schreibe lokal eine Datei test_nimm.py mit unittest — zwei Tests, dann python3 test_nimm.py.

Hinweis: Lokal ausführen: python3 test_nimm.py — unittest findet alle test…-Methoden von selbst.

Musterlösung zeigen
import unittest

def nimm(inventar, raum_items, name):
    if name not in raum_items:
        return False
    raum_items.remove(name)
    inventar.append(name)
    return True

class TestNimm(unittest.TestCase):
    def test_nimmt_item(self):
        inventar, boden = [], ["schlüssel"]
        self.assertTrue(nimm(inventar, boden, "schlüssel"))
        self.assertEqual(inventar, ["schlüssel"])

    def test_fehlschlag_bei_unbekannt(self):
        self.assertFalse(
            nimm([], ["schlüssel"], "drache"))

if __name__ == "__main__":
    unittest.main()

Erst überlegen, dann aufklappen — so trainiert es am meisten!

  1. Was passiert bei assert 1 > 2?
  2. Ein Test läuft durch und gibt nichts aus. Ist er bestanden?
  3. Brauchst du für unittest ein pip install?
  4. Warum lohnt sich ein Test für nimm, bevor du an ihm änderst?
  5. Wann schauen dir Leute pytest an?
Quiz-Lösungen anzeigen
  1. Python wirft einen AssertionError — die Behauptung war falsch.
  2. Ja — keine Ausgabe und kein Fehler heißt: alle Behauptungen stimmen.
  3. Nein — unittest gehört zur Standardbibliothek und kommt mit Python.
  4. Weil der Test sofort schreit, wenn die Änderung Inventar oder Raum still zerstört — statt drei Tage später.
  5. Später, wenn du lokal an größeren Projekten arbeitest — pytest ist bequemer, aber nichts für den Browser-Einstieg.

Mehr aus der Kategorie „Python lernen“

← Zurück zum Lehrpfad