Informatik

Debugging: Fehler systematisch finden und beheben

Debugging: Fehler systematisch finden und beheben
Debugging: Fehler systematisch finden und beheben
Für Quiz, Lückentext, Lernkarten und Fortschritt ist JavaScript nötig. Alle Inhalte und Lösungen bleiben direkt lesbar.

Debugging bedeutet, die Ursache eines Programmfehlers gezielt zu finden, zu beheben und die Korrektur anschließend zu prüfen. Du suchst also nicht planlos im gesamten Code: Du reproduzierst den Fehler, grenzt ihn ein und vergleichst erwartetes mit tatsächlichem Verhalten.

Deine Lernziele

Hake ab, was du schon kannst — und komm am Ende hierher zurück!

Testen zeigt den Fehler – Debugging erklärt ihn

Ein Bug ist ein Fehler, durch den ein Programm nicht wie vorgesehen arbeitet. Das sichtbare Problem ist jedoch nicht immer die eigentliche Ursache.

Definition

Testen

Beim Testen vergleichst du das beobachtete Ergebnis eines Programms mit dem erwarteten Ergebnis. Ein fehlgeschlagener Test zeigt, dass etwas nicht stimmt.

Definition

Debugging

Beim Debugging lokalisierst du den Fehler, erklärst seine Ursache, korrigierst ihn und prüfst die Korrektur. Debugging klärt also, warum der Test fehlschlägt.

Beispiel

Eine Anmeldung lässt ein gesperrtes Konto zu. Der Test zeigt das falsche Verhalten. Beim Debugging untersuchst du anschließend die geprüften Bedingungen und stellst fest, dass die Kontosperre in der Entscheidung nicht richtig berücksichtigt wird.

Merke

Testen entdeckt eine Abweichung. Debugging findet und beseitigt ihre Ursache. Beide Tätigkeiten gehören zusammen.

Teste dich
Frage 1 von 1LeichtEin Test liefert statt des erwarteten Ergebnisses ein falsches Ergebnis. Was weißt du dadurch sicher?
Lösung: Das beobachtete Verhalten weicht vom erwarteten Verhalten ab. — Der Test weist das Problem nach. Erst das Debugging lokalisiert und erklärt die Ursache.
Drei wichtige Fehlerarten erkennen

Nicht jeder Fehler zeigt sich auf dieselbe Weise. Die Fehlerart liefert dir einen ersten Hinweis für die Suche.

FehlerartWoran erkennst du sie?Beispiel
SyntaxfehlerDer Code verletzt Schreibregeln der Programmiersprache und kann häufig nicht gestartet werden.Eine schließende Klammer fehlt.
LaufzeitfehlerDer Fehler entsteht beim Start oder während der Ausführung.Das Programm versucht, durch null zu teilen.
LogikfehlerDas Programm läuft, liefert aber ein unerwünschtes Ergebnis.Eine falsche Bedingung gewährt Zugriff.

Ein Logikfehler ist oft besonders schwer zu entdecken: Das Programm stürzt nicht unbedingt ab. Deshalb brauchst du Testfälle mit klaren Erwartungswerten.

Teste dich
Frage 1 von 1LeichtEin Programm läuft ohne Fehlermeldung, berechnet aber regelmäßig den falschen Preis. Welche Einordnung passt am besten?
Lösung: Logikfehler — Das Programm ist ausführbar, folgt aber einer falschen Logik und erzeugt deshalb ein unerwünschtes Ergebnis.
In sechs Schritten von der Beobachtung zur Lösung

Ein belastbarer Debugging-Prozess besteht aus sechs Schritten:

  1. Fehler reproduzieren: Stelle die auslösenden Eingaben und Bedingungen möglichst genau nach.
  2. Fehler lokalisieren: Grenze den betroffenen Bereich mit Tests, Logs, Ausgaben oder einem Debugger ein.
  3. Ursache bestimmen: Suche die erste Stelle, an der der tatsächliche Zustand von der Erwartung abweicht.
  4. Fehler beheben: Ändere gezielt den ursächlichen Code.
  5. Korrektur validieren: Wiederhole den fehlgeschlagenen Test und prüfe weitere betroffene Funktionen.
  6. Vorgehen dokumentieren: Halte Ursache, Änderung und erfolgreiche Tests fest.
Gut zu wissen

Eine Beschreibung wie „Die Anmeldung geht manchmal nicht“ reicht für eine genaue Diagnose selten aus. Notiere Eingaben, Programmzustand, Fehlermeldung und die Schritte bis zum Fehler. So wird aus einem vagen Problem ein reproduzierbarer Fall.

Teste dich
Frage 1 von 1MittelDu hast einen Fehler beobachtet, aber noch nicht zuverlässig erneut ausgelöst. Was ist der sinnvollste nächste Schritt?
Lösung: Die auslösenden Bedingungen und Eingaben genauer erfassen und nachstellen. — Eine reproduzierbare Situation schafft eine stabile Grundlage für das Eingrenzen und für den späteren Wiederholungstest.
Die erste falsche Zustandsänderung finden

Beim Eingrenzen vergleichst du an mehreren Stellen den Soll-Zustand mit dem Ist-Zustand. Entscheidend ist nicht nur die Stelle, an der das falsche Ergebnis sichtbar wird. Suche die erste Stelle, an der ein Wert oder eine Entscheidung falsch wird.

Beispiel

Eine Anmeldefunktion soll nur dann wahr liefern, wenn das Passwort korrekt und das Konto nicht gesperrt ist.

Die fehlerhafte Bedingung lautet: passwort_korrekt oder nicht konto_gesperrt.

Passwort korrekt?Konto gesperrt?ErwartetFehlerhafte Bedingung
janeinwahrwahr
jajafalschwahr
neinneinfalschwahr

Beim ersten Fall bleibt der Bug verborgen. Die anderen Fälle zeigen, dass ein einziger günstiger Teil der Oder-Bedingung genügt. Die erste falsche Zustandsänderung entsteht deshalb bei der Auswertung dieser Bedingung.

Die gezielte Korrektur lautet: passwort_korrekt und nicht konto_gesperrt. Danach werden alle drei Fälle erneut getestet.

Mit verschiedenen Techniken kannst du solche Abweichungen sichtbar machen:

  • Ein Haltepunkt stoppt das Programm an einer gewählten Stelle.
  • Die schrittweise Ausführung führt jeweils die nächste Codezeile aus.
  • Die Variableninspektion zeigt aktuelle Werte und Zustände.
  • Print-Ausgaben und Logs protokollieren Werte und Programmabläufe.
  • Beim Prinzip Teile und herrsche schließt du fehlerfreie Bereiche aus und verkleinerst den verdächtigen Abschnitt.
  • Beim Backtracking verfolgst du den Ablauf vom sichtbaren Fehler rückwärts.
  • Beim Rubber Duck Debugging erklärst du den Code Zeile für Zeile in einfachen Worten. Dabei können unklare Annahmen auffallen.
Teste dich
Frage 1 von 1MittelEin Fehler tritt nur im laufenden Produktionssystem auf. Du kannst dort keinen interaktiven Debugger anhalten. Welche Grundlage hilft am ehesten bei der Diagnose?
Lösung: Aussagekräftige Logs mit Zuständen und Ablaufhinweisen — Logs zeichnen Zustände und Abläufe auf. Sie eignen sich besonders, wenn ein Fehler nicht lokal oder interaktiv untersucht werden kann.
Mit Testfällen die Korrektur belegen

Eine Codeänderung allein beweist noch nicht, dass der Bug behoben ist. Wiederhole zuerst genau den Test, der den Fehler sichtbar gemacht hat. Prüfe danach weitere Fälle, damit die Korrektur keine neue Störung verursacht.

Für eine Funktion sind drei Arten von Testfällen besonders nützlich:

  • Ein Normalfall prüft eine typische gültige Eingabe.
  • Ein Randfall prüft einen Wert direkt an einer festgelegten Grenze.
  • Ein ungültiger Fall prüft, wie das Programm mit einer nicht erlaubten Eingabe umgeht.
Beispiel

Für diese Übung gilt die Spezifikation: zugang_erlaubt(alter) akzeptiert ganze Zahlen von 0 bis 120. Ab 16 soll die Funktion wahr liefern. Andere Eingaben sollen abgewiesen werden.

TestartEingabeErwartung
Normalfall20wahr
Randfall unter der Grenze15falsch
Randfall an der Grenze16wahr
Ungültiger FallsechzehnEingabe wird abgewiesen

Die beiden Randfälle prüfen beide Seiten der entscheidenden Grenze. Nur 20 zu testen wäre zu schwach: Eine fehlerhafte Grenze könnte dabei unentdeckt bleiben.

Unit-Tests prüfen den geänderten kleinen Codebereich. Integrationstests prüfen sein Zusammenspiel mit einem Modul, Systemtests das Gesamtsystem. Regressionstests kontrollieren, ob die Änderung bisher funktionierende Bereiche beschädigt hat.

Lückentext

Wähle in jeder Lücke die passende Form und prüfe anschließend deine Antworten.

Beim Testen vergleichst du . Debugging sucht einer Abweichung. Nach der Korrektur prüfen , ob andere Funktionen weiterhin richtig arbeiten.

Lösungen: Lücke 1: beobachtetes und erwartetes Verhalten; Lücke 2: die Ursache; Lücke 3: Regressionstests. Ein vollständiger Fehlerzyklus verbindet Beobachtung, Ursachenanalyse, gezielte Korrektur und erneute Prüfung.
Karteikasten
Karteikasten

Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.

Alles auf einen Blick
Mindmap
  • Debugging
    • Ausgangspunkt: Fehler reproduzieren
    • Diagnose: Abweichung lokalisieren und Ursache bestimmen
    • Beobachtung: Debugger, Print-Ausgaben und Logs nutzen
    • Korrektur: ursächlichen Code gezielt ändern
    • Nachweis: Wiederholungs- und Regressionstests ausführen
    • Abschluss: Ursache, Änderung und Tests dokumentieren
Abschluss-Check
Teste dich
Frage 1 von 3LeichtWas unterscheidet Debugging vom reinen Testen?
Lösung: Debugging sucht und behebt die Ursache einer festgestellten Abweichung. — Testen und Debugging ergänzen sich: Der Test zeigt die Abweichung, Debugging erklärt und beseitigt sie.
Frage 2 von 3MittelEine Berechnung liefert nur beim Grenzwert ein falsches Ergebnis. Was solltest du zuerst untersuchen?
Lösung: Die Bedingung, die den Grenzwert verarbeitet, und die Zustände unmittelbar davor — Ein gezielter Randfall weist auf die Grenzbedingung hin. Vergleiche dort erwartete und tatsächliche Werte Schritt für Schritt.
Frage 3 von 3SchwerNach einer Änderung besteht der ursprünglich fehlgeschlagene Test. Welcher Nachweis fehlt noch für eine belastbare Korrektur?
Lösung: Weitere betroffene Testfälle und Regressionstests müssen ebenfalls bestehen. — Wiederhole nicht nur den ursprünglichen Fall. Normal-, Rand- und ungültige Fälle sowie passende Regressionstests zeigen, ob die Korrektur zuverlässig ist.

Du kannst erfolgreich debuggen, wenn du nicht beim sichtbaren Symptom stehen bleibst: Reproduziere den Fehler, finde die erste falsche Zustandsänderung, ändere die Ursache gezielt und belege die Korrektur mit passenden Tests.

Passend dazu