Der Branchendurchschnitt der Softwareindustrie in den 1980er Jahren lag bei 30 bis 60 Defekten pro tausend Codezeilen. Das IBM Cleanroom-Team lieferte einen 20.000-Zeilen-Compiler-Inkrement mit 53 in Tests gefundenen Defekten aus. Das sind 2,6 pro KLOC. Einzelne Inkremente von 10.000 Zeilen gingen mit null gefundenen Defekten in den Systemtest.
Das Seltsamste daran? Den Programmierern war es verboten, ihren eigenen Code auszuführen.
Was Cleanroom software engineering tatsächlich bedeutet
Cleanroom software engineering, entwickelt vom Mathematiker Harlan Mills bei IBM in den 1980er Jahren, ist ein theoriebasierter Prozess, der auf formal specification, structured design und mathematical correctness verification statt Unit Testing und Debugging setzt. Der Name stammt aus der Halbleiterfertigung. In einem Chip-Fab führt man keinen Staub ein, um ihn später wieder abzuwischen. Man verhindert die Kontamination von vornherein.
Bei Cleanroom führen Entwickler kein Unit Testing durch. Sie debuggen nicht. Sie verifizieren.
Der Prozess teilt Software in Inkremente auf, typischerweise 5.000 bis 15.000 Zeilen Code. Jedes Inkrement wird spezifiziert, entworfen, verifiziert und dann als vollständige Einheit statistisch getestet. Die Entwickler schreiben den Code, dürfen ihn aber während der Entwicklung weder kompilieren noch ausführen. Das erste Mal, dass der Code läuft, ist während des formalen Systemtests.
Wie box structure verification das Debugging ersetzt
Der Kernmechanismus ist die box structure specification. Jede Komponente wird auf drei Ebenen definiert.
Die black box spezifiziert das externe Verhalten. Sie definiert Stimuli und Reaktionen, ohne internen Zustand zu erwähnen.
Die state box fügt die internen Zustandsvariablen und die Zustandsübergangsfunktion hinzu.
Die clear box ist die eigentliche Implementierung, die eine strukturierte Verfeinerung der state box sein muss.
Diese Hierarchie ist wichtig, weil sie es ermöglicht, die Korrektheit auf jeder Ebene unabhängig zu verifizieren. Man beweist, dass die state box die black box implementiert, und dass die clear box die state box implementiert.
So sieht das in der Praxis für eine Funktion mit einem nicht-trivialen correctness argument aus:
from typing import Optional
def binary_search(arr: list[int], target: int) -> Optional[int]:
"""
Black box spec:
Pre: arr is sorted in non-decreasing order.
Post: Returns index i such that arr[i] == target,
or None if target is not present.
"""
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return None
Das verification argument für die Schleife ist das Entscheidende. Das Team prüft dies gemeinsam und bestätigt drei Tatsachen. Erstens, wenn arr[mid] == target, ist die Postcondition sofort erfüllt. Zweitens, wenn arr[mid] < target, kann das target nur an Indizes größer als mid existieren, also bewahrt low = mid + 1 die Invariante, dass das target in arr[low:high+1] liegt, falls es überhaupt existiert. Drittens, wenn arr[mid] > target, gilt das symmetrische Argument für high = mid - 1.
Das ist kein Code Review, bei dem jemand fragt, ob du an leere Arrays gedacht hast. Das ist ein strukturierter Gruppenbeweis, dass jede mögliche Eingabe die spezifizierte Ausgabe produziert.
Die IBM-Zahlen hinter dem Zero-Defect-Anspruch
IBM setzte Cleanroom bei drei großen Projekten in den späten 1980er und frühen 1990er Jahren ein: der COBOL Structuring Facility (40.000 Zeilen), einem Air-Force-Helikopter-Flugprogramm (35.000 Zeilen) und einem NASA-Raumtransport-Planungssystem (45.000 Zeilen).
Die COBOL/SF-Daten sind die detailliertesten. Das erste 20.000-Zeilen-Inkrement wurde mit formal specifications, box structure design und Gruppen-correctness verification entwickelt. Den Entwicklern war es nicht erlaubt, ihre Module während der Entwicklung zu kompilieren oder auszuführen. Der Code ging direkt in den Systemtest.
Ergebnis: 53 Defekte wurden während des Tests gefunden. Mehr als 90 % aller Defekte wurden in der Verifikationsphase erkannt, bevor der Code überhaupt ausgeführt wurde.
Zum Vergleich: Bei konventionellen IBM-Projekten der Zeit wurden etwa 60 % der Defekte vor der Ausführung gefunden. Cleanroom drehte das Verhältnis um.
Einige Inkremente, insbesondere kleinere unter 10.000 Zeilen, wiesen null im Systemtest gefundene Defekte auf. Hierher stammt die Behauptung der „10.000 Zeilen mit null Defekten”. Es ist passiert. Es war nicht universell, aber es war reproduzierbar genug, dass IBM es zu einem Standardbenchmark machte.
Warum das Nicht-Ausführen des eigenen Codes zu weniger Bugs führt
Das ist der Teil, der Entwicklern den Verstand bricht. Wie kann Nicht-Testen zu besserem Code führen?
Die Antwort ist kognitiv, nicht technisch. Wenn du weißt, dass du den Code nicht ausführen kannst, um deine Arbeit zu prüfen, entwirfst du sorgfältiger. Du schreibst kleinere Funktionen. Du denkst über Edge Cases nach, bevor du tippst. Du stützt dich auf das Type System und strukturierte Programmierung, weil du kein Sicherheitsnetz hast.
Es ist der gleiche Grund, warum Chirurgen Checklisten verwenden. Die Einschränkung erzwingt einen anderen mentalen Modus.
Es gibt auch eine statistische Qualitätskontrollschicht. Cleanroom verwendet statistical usage testing basierend auf einem operational profile. Testfälle werden aus der Wahrscheinlichkeitsverteilung des tatsächlichen Nutzerverhaltens gezogen, nicht aus der Vermutung des Entwicklers, wo die Bugs sind. Das bedeutet, du misst Zuverlässigkeit, nicht nur Bug-Jagd.
Die Trade-offs, die Cleanroom Nischenstatus hielten
Cleanroom hat nicht die Welt erobert. Es gibt Gründe.
Erstens ist die Trainingsbarriere hoch. Du brauchst Teams, die formal specifications schreiben und mathematische correctness arguments konstruieren können. Die meisten CS-Absolventen im Jahr 2025 haben noch nie einen formalen Beweis für eine nicht-triviale Funktion geführt.
Zweitens sind die upfront Design-Kosten hoch. IBM berichtete, dass specification text das Design text bei vier zu eins überstieg auf dem COBOL/SF-Projekt. Du tauschst Design-Zeit gegen Test-Zeit. Das funktioniert für Compiler und Flugsoftware. Es funktioniert nicht für eine CRUD-App mit wöchentlichen Pivot-Anforderungen.
Drittens bezieht sich die Zero-Defect-Behauptung auf defect density, nicht auf das Fehlen aller Bugs. Ein Cleanroom-Inkrement kann immer noch specification errors haben. Wenn die black box falsch ist, ist die verifizierte clear box auch falsch, nur konstruktionsbedingt.
Wie man die Cleanroom-Disziplin stiehlt, ohne die Bürokratie
Du kannst wahrscheinlich nicht das volle Cleanroom übernehmen. Dein Produktmanager wird nicht auf ein vier-zu-eins-Spec-zu-Code-Verhältnis warten. Aber du kannst die wertvollen Teile stehlen.
1. Schreibe den Contract vor der Implementierung.
Verwende preconditions, postconditions und invariants, um deine black box zu definieren. Selbst informelle Kommentare zwingen dich dazu, vor der Optimierung über Grenzen nachzudenken.
from typing import List, Tuple
def partition(nums: List[int], pivot: int) -> Tuple[List[int], List[int]]:
"""
Black box spec:
Pre: True (any list of integers is valid).
Post: left contains exactly the elements of nums where x <= pivot.
right contains exactly the elements of nums where x > pivot.
len(left) + len(right) == len(nums).
"""
left = [x for x in nums if x <= pivot]
right = [x for x in nums if x > pivot]
# Runtime checks act as lightweight verification witnesses.
assert all(x <= pivot for x in left)
assert all(x > pivot for x in right)
assert len(left) + len(right) == len(nums)
return left, right
2. Ersetze einige Unit Tests durch verification arguments.
Bevor du den Test schreibst, schreibe einen einzeiligen Argumentationsstrang, warum der Code korrekt ist. Wenn du diesen Satz nicht konstruieren kannst, ist das Design zu komplex. Das ist die einzeln effektivste Cleanroom-Praxis für moderne Teams.
3. Verwende property-based testing als statistical usage testing.
Tools wie Hypothesis in Python oder fast-check in JavaScript generieren Eingaben aus einer Verteilung. Das ist spirituell näher an Cleanrooms statistical testing als beispielbasierte Unit Tests.
4. Trenne Kompilierung von Verifikation.
Wenn du gewohnheitsmäßig eine Zeile schreibst, kompilierst, den Tippfehler korrigierst, die nächste Zeile schreibst, debuggst du per Zuckreflex. Versuche, eine vollständige logische Einheit zu schreiben, bevor du sie ausführst. Das Unbehagen ist der Punkt.
FAQ
Wird Cleanroom heute noch verwendet?
Es überlebt in sicherheitskritischen und missionskritischen Domänen. NASA, die FAA und einige Medizingerätehersteller verwenden Varianten des Prozesses. Es ist selten in kommerzieller Software.
Kann ich wirklich Code ohne Unit Testing ausliefern?
Nur wenn du es durch etwas gleichermaßen Rigoreses ersetzt. Cleanroom-Teams verbrachten mehr Stunden mit Verifikation als die meisten Teams mit Testing. Die Zeit ist nicht verschwunden. Sie ist nach links verschoben.
Garantiert Cleanroom null Bugs?
Nein. Es garantiert, dass die Implementation mit hoher Wahrscheinlichkeit der specification entspricht. Wenn die specification falsch ist, wird der Bug perfekt bewahrt.
Wie war die Produktivitätsauswirkung?
IBM berichtete eine Produktivität von mehr als 400 Zeilen Code pro Person-Monat auf dem COBOL/SF-Projekt, weil die drastisch reduzierte Testzeit den erhöhten Design-Aufwand ausglich.
Fazit
Das nächste Mal, wenn jemand behauptet, eine Methodik liefere Zero-Defect-Software, frag nach den Projektdaten. IBMs Cleanroom-Zahlen sind real, aber sie kamen aus einem spezifischen Kontext: erfahrene Teams, formales Training, inkrementelle Auslieferung und die Bereitschaft, zu verifizieren statt zu debuggen.
Das 10.000-Zeilen-Inkrement mit null Defekten ist erreichbar. Es kostet nur mehr Weitsicht, als die meisten Organisationen zu zahlen bereit sind.