Zum Inhalt springen
Zurück zum Blog
Architektur 5 Min. Lesezeit

Fehler an Stellen, die keiner angefasst hat: Was Tests dagegen tun

Software, die läuft, ist noch lange nicht leicht zu ändern. Der Artikel zeigt an einem Lagerbeispiel, woran du technische Schulden ohne Blick in den Code erkennst, was sie kosten und wie ein automatischer Test eine Geschäftsregel bei jeder Änderung absichert.

Monatsende, Inventur im Kühllager. Drei Paletten Joghurt sind abgelaufen und müssen abgeschrieben werden. Dabei folgt die Lagersoftware einer klaren Regel: Was zuerst abläuft, geht zuerst raus.

Die Suche nach der Ursache dauert zwei Tage. An der Kommissionierung hat niemand etwas geändert. Umgebaut wurde nur die Lagerliste: Die neueste Charge sollte oben stehen, damit der Wareneingang sie schneller findet. Lagerliste und Kommissionierung nutzen aber dieselbe Sortierung. Seitdem schickt die Software die Kommissionierer zuerst zur frischen Ware.

Das Beispiel ist ausgedacht. Das Gefühl dahinter kennen viele: Die Software läuft jeden Tag, aber keiner traut sich mehr ran, weil niemand sicher sagen kann, was eine Änderung sonst noch bewirkt. Oft fehlt etwas, das man am Anfang nicht sieht: automatische Tests.

In diesem Artikel erfährst du, wie aus funktionierender Software schwer änderbare Software wird, woran du das ohne Blick in den Code erkennst und wie ein Test eine Regel festhält.

Läuft heißt nicht: lässt sich ändern

Software ist nach dem Start nicht fertig. Neue Kunden bringen neue Anforderungen, die Buchhaltung neue Regeln, der Spediteur eine neue Schnittstelle. Jede Änderung trifft auf Code, den jemand vor Monaten geschrieben hat.

Was sich dabei anhäuft, nennen Entwickler technische Schulden: Abkürzungen, die heute Zeit sparen und später Zinsen kosten. Die Zinsen zahlst du mit langsameren Änderungen und häufigeren Fehlern (proxworks, tenmedia). Unzureichende Tests zählen ausdrücklich dazu, genau wie unsauberer Code und fehlende Dokumentation (escape).

Am Anfang merkt man davon wenig. Die Software tut, was sie soll. Mit der Zeit werden Updates komplexer, riskanter und aufwendiger. Das Budget fließt dann in die Reparatur von Bestehendem statt in neue Funktionen (escape).

Drei Warnzeichen, für die du keinen Code lesen musst

Technische Schulden erkennst du an ihren Folgen (proxworks):

  • Kleine Änderung, große Schätzung. Eine zusätzliche Spalte in der Lagerliste soll eine Woche dauern.
  • Fehler an Stellen, die keiner angefasst hat. Die Lagerliste wird umgebaut, danach kommissioniert das Lager falsch.
  • Lange Einarbeitung. Wer neu ins Team kommt, braucht lange, bis er sich an etwas herantraut.

Hinter allen dreien steckt oft dieselbe Unsicherheit: Niemand weiß genau, was eine Änderung sonst noch bewirkt. Also wird großzügig geschätzt, lange gesucht und trotzdem etwas übersehen.

Was die Zinsen kosten

Eine Kosten-Nutzen-Analyse für Unternehmenssysteme kommt zu dem Ergebnis: Entwickler verbringen im Schnitt 42 Prozent ihrer Arbeitszeit mit technischen Schulden und Wartung. Die Schulden selbst können 20 bis 40 Prozent des Gesamtwerts eines Technologiebestands ausmachen (American Impact Review). Eine weitere Übersicht nennt 23 bis 42 Prozent der Arbeitszeit für die Behebung von Altlasten und hält fest, dass 92 Prozent der Unternehmen unter technischen Schulden leiden (alphacoders).

Übersetzt auf eine Arbeitswoche: Im Schnitt gehen rund zwei von fünf Tagen für technische Schulden und Wartung drauf. Diese Zeit fehlt für das, was dein Geschäft voranbringt.

Von allein wird es nicht besser. Eine Studie zum Entwicklungsaufwand zeigt: Bei einem hohen Grad an technischen Schulden sinkt die Entwicklungsgeschwindigkeit drastisch, die Kosten für Wartung und neue Funktionen können mit der Zeit exponentiell steigen (arXiv). Die American Impact Review beschreibt das als Zinseszins: weniger Tempo, mehr Fehler, mehr Risiko im Betrieb.

Technische Schulden tilgt niemand nebenbei. Wer sie liegen lässt, zahlt mit jeder Änderung mehr.

Ein Test hält die Regel fest

Ein automatischer Test ist ein kleines Programm, das prüft, ob dein Programm in einem bestimmten Fall noch das Richtige tut. Er hält diesen Fall fest und prüft ihn bei jeder Änderung, ohne dass jemand daran denken muss.

So sieht das für die Lagerregel aus der Einleitung aus. Du musst kein TypeScript können, um es zu lesen:

TypeScript
// kommissionierung.test.ts – lauffähig mit: npx vitest run
import { describe, expect, it } from "vitest";

// Hausregel (Beispiel, ausgedacht): Was zuerst abläuft, geht zuerst raus.
// MHD als ISO-Datum ("2026-10-20"), so stimmt die Reihenfolge auch beim Textvergleich.
type Charge = { nummer: string; mhd: string };

// Lagerliste und Kommissionierung nutzen beide diese Sortierung.
function chargenNachMhd(chargen: Charge[]): Charge[] {
  // Eine Kopie sortieren, die Ausgangsliste bleibt unverändert.
  return [...chargen].sort((a, b) => a.mhd.localeCompare(b.mhd));
}

function naechsteCharge(chargen: Charge[], versandtag: string): string | null {
  // Abgelaufene Ware wird nicht mehr verschickt.
  const verfuegbar = chargenNachMhd(chargen).filter((c) => c.mhd >= versandtag);
  return verfuegbar[0]?.nummer ?? null;
}

const LAGER: Charge[] = [
  { nummer: "C-0815", mhd: "2026-12-01" },
  { nummer: "C-0702", mhd: "2026-11-05" },
  { nummer: "C-0650", mhd: "2026-10-20" },
];

describe("Kommissionierung", () => {
  it("schickt zuerst raus, was zuerst abläuft", () => {
    expect(naechsteCharge(LAGER, "2026-10-19")).toBe("C-0650");
  });

  it("lässt abgelaufene Ware im Lager", () => {
    expect(naechsteCharge(LAGER, "2026-10-21")).toBe("C-0702");
  });
});

Die beiden Funktionen oben sind die Regel. Die beiden Blöcke unten, die mit it beginnen, sind die Tests, und ihre Namen lesen sich wie ein Satz: Bei Versand am 19. Oktober muss Charge C-0650 raus, weil sie als erste abläuft. Zwei Tage später ist sie abgelaufen, dann ist C-0702 dran.

Jetzt baut jemand die Lagerliste um und dreht die Sortierung, damit die neueste Charge oben steht. Ohne Tests fällt das erst bei der Inventur auf. Mit Tests schlagen beide an, sobald die Änderung in die Pipeline geht: Die Software will C-0815 verschicken, die frischeste Ware. Der Fehler wird behoben, bevor die erste Kiste falsch kommissioniert ist. Die Lagerliste bekommt eine eigene Sortierung, die Versandregel bleibt, wie sie ist.

Illustration: Eine Regel, zwei Nutzer, ein Wächter

Nebenbei lesen sich die Tests wie eine Beschreibung der Regel. Wer neu ins Team kommt, sieht, was gelten soll, und muss es nicht aus dem Code erraten.

Einen Haken hat das: Geprüft wird nur, was ein Test festhält. Eine Regel ohne Test ist so ungeschützt wie vorher. Deshalb gehört zu jeder Funktion ein Test, nicht nur zu ein paar ausgewählten. Mehrere Quellen nennen zusätzliche automatisierte Tests als Mittel gegen technische Schulden (NetRom, alphacoders, proxworks).

Wenn die Software schon ein paar Jahre läuft

Alles neu schreiben ist selten die Antwort. Die Quellen nennen drei Wege, Schulden schrittweise abzubauen:

  • Boy-Scout-Regel: Jede Stelle, die man ohnehin anfasst, besser hinterlassen und dort Tests ergänzen (alphacoders, tenmedia).
  • Logik zusammenführen: Eine Regel, die an drei Stellen steht, an eine Stelle holen und dort mit Tests absichern (proxworks).
  • Strangler-Fig-Pattern: Das Altsystem Stück für Stück durch neue, getestete Teile ablösen, statt alles auf einmal umzustellen (tenmedia).

Für das nächste Projekt gilt: Tests gehören in den Preis, nicht in eine spätere „Phase 2“.

Bei Mavaris ist das gesetzt: Jede Funktion ist mit automatischen Tests abgesichert, damit die Software auch in fünf Jahren noch läuft. Der Grund ist ganz praktisch. Wir arbeiten mit festen Preisen und tragen das Risiko für Mehraufwand selbst. Die Zinsen für fehlende Tests würden wir also selbst zahlen. Und weil wir eigene Produkte betreiben, kennen wir diese Rechnung aus erster Hand.

Wenn du bei dir einen Anfang suchst: Nimm die eine Regel, deren Fehler am meisten kosten würde, und frag nach, ob ein Test sie festhält. Im Kühllager aus dem Beispiel wäre das ein einziger Satz gewesen: Was zuerst abläuft, geht zuerst raus.

  • Architektur
  • Bestandssysteme

Artikel teilen

LinkedIn ↗

Kennenlernen

Dieselbe Frage bei dir? Lass uns schnacken.

Kostenlos und direkt mit dem Entwickler. Danach weißt du, ob wir die Richtigen sind. Wenn nicht, sagen wir dir das.

Du sprichst direkt mit Marcel

Gründer von Mavaris

Lass uns schnacken

Wir schlagen dir Termine vor, 30 Minuten per Video.

oder schreib an moin@mavaris.de

Diagramm