Jede Website hat Bugs. Nicht, weil die Menschen, die sie bauen, unsorgfältig wären, sondern weil eine Website aus vielen kleinen Entscheidungen besteht, getroffen von verschiedenen Leuten, für Inhalte, die noch niemand geschrieben hat, und für Geräte, die niemand im Team besitzt. Die Frage ist nicht, ob Bugs entstehen, sondern wann Sie sie finden.
In diesem Beitrag geht es darum, woher Bugs kommen, warum der Zeitpunkt des Fundes über die Kosten entscheidet und was ich tue, um sie so früh wie möglich zu finden.
Warum Bugs entstehen
Unklare Anforderungen
Viele Bugs sind keine Fehler im Code, sondern im Verständnis. „Das Formular soll eine E-Mail schicken“ lässt offen, wer sie bekommt, was bei einem Fehler passiert und ob der Besucher eine Bestätigung erhält. Der Code tut genau das, was gebaut wurde, und trotzdem nicht das, was gemeint war.
Annahmen über Daten
Code wird gegen die Inhalte geschrieben, die es beim Entwickeln gibt. Echte Inhalte kommen später: ein Projekt ohne Website, ein Name mit Umlaut, ein Titel dreimal so lang wie im Design gedacht, eine leere Liste. Jeder dieser Fälle ist ein Zweig, den der Code während der Entwicklung nie durchlaufen hat.
Sonderfälle, die lokal niemand sieht
Manche Bugs gibt es nur bei anderen. Ein Klassiker: Datumsangaben. Ein Datum ohne Uhrzeit wird als Mitternacht UTC gelesen, und in der Zeitzone des Besuchers formatiert kann es auf den Vortag rutschen:
// The post was published on 6 November.
const published = new Date("2026-11-06");
published.toLocaleDateString("en-US");
// Berlin: "11/6/2026"
// New York: "11/5/2026" ← a day earlyAuf dem Rechner eines Entwicklers in Berlin sieht alles richtig aus. Die Lösung ist eine einzige Option, sobald man den Bug kennt:
// Date-only strings are parsed as midnight UTC, so format them in UTC too.
published.toLocaleDateString("en-US", { timeZone: "UTC" });
// "11/6/2026" everywhereÄnderungen, die anderes kaputt machen
Eine Änderung am Header-CSS repariert das mobile Menü und verschiebt den Footer. Ein umbenanntes Feld im CMS vereinfacht die Arbeit der Redaktion und leert einen Bereich auf der Startseite. Solche Regressionen sind besonders teuer, weil der kaputte Teil bereits getestet war und niemand ihn noch einmal ansieht.
Unterschiedliche Umgebungen
Safari auf einem älteren iPhone, eine langsame Mobilverbindung, eine Browser-Erweiterung, die ein Skript blockiert, ein Screenreader. Eine Website, die in einem Browser auf einem schnellen Laptop perfekt läuft, ist erst in einer von vielen Umgebungen getestet, in denen sie laufen wird.
Je früher ein Bug gefunden wird, desto günstiger ist er
Derselbe Bug kostet sehr unterschiedlich viel, je nachdem, wann er auftaucht. Grob gibt es diese Stufen:
- Beim Schreiben des Codes: Editor oder Typprüfung melden ihn. Die Korrektur dauert Sekunden, der ganze Kontext ist noch im Kopf.
- Im Review oder Test: Jemand anderes findet ihn. Sie müssen sich wieder in die Aufgabe hineindenken, aber außerhalb des Projekts merkt es niemand.
- Vor dem Launch, durch den Kunden: Es kostet eine Feedbackrunde, eine Korrektur und etwas Vertrauen.
- Nach dem Launch, durch einen Besucher: Jetzt kostet er auch, was der Besucher nicht getan hat: die Anfrage, die nicht abgeschickt wurde, den Kauf, der nicht stattfand. Oft meldet ihn niemand.
Die Korrektur selbst sind auf jeder Stufe oft dieselben paar Zeilen. Was wächst, ist alles drumherum: die Ursache in Code finden, den man vor Wochen geschrieben hat, mehr Beteiligte, falsch gespeicherte Daten bereinigen und die Kunden, die verloren gingen, solange der Bug live war.
Ein Bug, der beim Tippen auffällt, kostet Sekunden. Derselbe Bug, den ein Kunde findet, kann den Kunden kosten.
Wie ich Bugs früher finde
Den Editor suchen lassen
TypeScript im Strict-Modus findet eine ganze Klasse von Bugs, bevor der Code überhaupt läuft. Hier ist die Website des Projekts optional, und TypeScript weigert sich, etwas anderes anzunehmen:
interface Project {
title: string;
website?: string;
}
function domain(project: Project) {
return new URL(project.website).hostname;
// error TS2345: Argument of type 'string | undefined' is not
// assignable to parameter of type 'string | URL'.
}Zwei Compiler-Optionen erledigen den Großteil:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true
}
}Kleine Tests für knifflige Logik
Nicht alles braucht einen Test. Logik mit Sonderfällen schon: Preise, Datumsangaben, alles, was formatiert oder rechnet. Eine kleine Funktion wie diese:
export function formatPrice(amount: number, locale: "en" | "de"): string {
return new Intl.NumberFormat(locale === "de" ? "de-DE" : "en-IE", {
style: "currency",
currency: "EUR",
}).format(amount);
}…enthält bereits eine Falle. Die deutsche Formatierung setzt ein geschütztes Leerzeichen vor das Euro-Zeichen. Ein Test mit normalem Leerzeichen schlägt fehl, und genau darum geht es: Er zeigt, wie die Ausgabe wirklich aussieht, bevor ein Layout oder ein Vergleich davon abhängt.
import { describe, expect, it } from "vitest";
import { formatPrice } from "./price";
describe("formatPrice", () => {
it("formats euros for German visitors", () => {
// Intl puts a non-breaking space (\u00a0) before the €, not a normal one.
expect(formatPrice(1234.5, "de")).toBe("1.234,50\u00a0€");
});
it("formats euros for English visitors", () => {
expect(formatPrice(0, "en")).toBe("€0.00");
});
});Früh mit echten Inhalten und echten Geräten
Ich arbeite so früh wie möglich mit echten oder realistischen Inhalten, inklusive der unbequemen Fälle: der längste Titel, das fehlende Bild, die deutsche Übersetzung. Und ich öffne die Website lange vor dem Launch auf einem echten Handy, nicht erst am letzten Tag.
Ein zweiter Blick
Jede Änderung geht vor dem Mergen durch ein Review, und automatische Prüfungen laufen bei jedem Pull Request. Wie diese Pipeline aussieht, steht in meinem Beitrag Was QA für eine Website bedeutet.
Das Fazit
Bugs gehören zur Softwareentwicklung dazu. Nicht normal ist, sie erst im Live-Betrieb zu finden, wenn sie schon im Editor aufgefallen wären. Der Großteil der Arbeit besteht darin, den Fund nach vorne zu verlegen: strengere Typen, kleine Tests, wo sie zählen, echte Inhalte, echte Geräte und ein Review, bevor etwas live geht.
Wenn Ihre Website Bugs hat, die immer wiederkommen, oder Sie einen Launch ohne Überraschungen möchten, schreiben Sie mir. Ich sage Ihnen, wo ich zuerst nachsehen würde.