Qualität als System: Coverage, zentrale Pakete und ein echter Bug
Foto: Burst · StockSnap (CC0 1.0), via Openverse
Qualität war bei Xircuit nie ein Mangel an gutem Willen. Es gab immer Tests, immer Reviews, immer die Sorgfalt, mit der man an Gesundheitsdaten herangeht. Was fehlte, war etwas Unbequemeres: ein System, das gute Absichten von der Tagesform entkoppelt. Ein Netz, das nicht davon abhängt, ob ich an einem müden Freitagabend daran denke, den letzten Zweig noch abzudecken.
Diese Woche ging es genau darum — Qualität nicht als Vorsatz, sondern als Mechanik. Ein Test-Coverage-Programm, das nicht mehr fragt, sondern verlangt. Eine Paketverwaltung, die verhindert, dass zwei Projekte heimlich unterschiedliche Versionen derselben Bibliothek ziehen. Und, fast wie zur Belohnung für die Mühe, ein echter Produktionsfehler, den dieses neue Netz beim Aufspannen selbst gefunden hat. Das ist die schönste Art von Bestätigung: nicht ein grüner Haken, sondern ein roter, der berechtigt war.
Von „wir testen" zu „es muss abgedeckt sein"
Der entscheidende Schritt in dieser Phase war kein neuer Test, sondern eine neue Regel. Bisher war Testabdeckung eine Kennzahl, die man beobachtete — eine Anzeige am Rand, die man zur Kenntnis nahm und dann doch übersah, wenn es schnell gehen musste. Das Coverage-Programm dieser Woche zog stattdessen ein Coverage-Gate über jede nicht ausgenommene Assembly und schaltete es auf Enforce. Der Unterschied zwischen „beobachten" und „erzwingen" ist der ganze Punkt: Ab jetzt bricht der Build, wenn die Abdeckung eines Bausteins unter seine vereinbarte Schwelle fällt.
Das klingt streng, und das ist gewollt. Ein Gate, das man mit einem Kommentar überstimmen kann, ist kein Gate, sondern eine Empfehlung. Wichtig war mir dabei aber die andere Seite derselben Medaille: die Ausnahmen. Nicht jede Assembly lässt sich sinnvoll auf dieselbe Zahl trimmen — reine Plattform-Bindungen, generierte Site-Templates oder dünne Hüllen um Fremd-SDKs sind ausdrücklich ausgenommen, damit die Zahl ehrlich bleibt und nicht durch Alibi-Tests aufgeblasen wird. Ein Gate ist nur so viel wert wie die Glaubwürdigkeit dessen, was es misst.
Wo die Abdeckung wirklich zählt
Nicht jeder Code ist gleich riskant, und deshalb hat sich die Arbeit dort konzentriert, wo ein Fehler am meisten weh tut. Der Auth0-Nahtpunkt — die Stelle, an der die gesamte Anmeldung und Autorisierung an den Identitätsanbieter andockt — erreichte 100 Prozent Abdeckung. Das ist die Sorte Code, bei der ein stiller Regressionsfehler nicht „eine Seite sieht komisch aus" bedeutet, sondern „jemand kommt rein, der nicht reinkommen sollte", oder umgekehrt. Solche Nähte verdienen die volle Zahl.
Ähnlich verhielt es sich mit den Zahlungen, die nun nahezu vollständig abgedeckt sind. Geldflüsse verzeihen keine Flüchtigkeitsfehler: Ein falsch behandelter Webhook, ein doppelt gebuchter Betrag, ein Abo, das nach der Kündigung weiterläuft — das sind keine kosmetischen Probleme, sondern Vertrauensbrüche. Und weil Xircuit viel im Browser rendert, bekam die geteilte UI über zusätzliche bUnit-Tests spürbar mehr Abdeckung. bUnit rendert Blazor-Komponenten in einem echten Komponenten-Kontext und lässt sich mit Klicks und Eingaben füttern, statt nur die Logik dahinter zu prüfen. So wandert die Prüfung näher an das, was ein Mensch tatsächlich sieht und anfasst.
Foto: Markus Spiske · Rawpixel (CC0 1.0), via Openverse
Ein echter Bug, gefunden beim Aufspannen des Netzes
Der schönste Moment dieser Woche war ein Fehlschlag. Beim Ausbau der Abdeckung — also genau dann, als die neuen Tests zum ersten Mal Wege durchspielten, die vorher niemand automatisiert abgeklopft hatte — fiel ein echter Produktionsfehler auf: Fünf medizinische Dialoge speicherten auf Hosts ohne UTC-Zeitzone nicht. Auf meinem Rechner und in den bisherigen Läufen war alles grün gewesen, weil dort die Zeitzone zufällig passte. Erst als ein Test die Umgebung bewusst anders stellte, brach die Sache auf.
Solche Fehler sind die tückischsten überhaupt, weil sie von der Umgebung abhängen und nicht vom Code allein. „Funktioniert bei mir" ist hier keine Beruhigung, sondern die eigentliche Falle: Ein Zeitstempel, der lokal korrekt erscheint, kippt auf einem Host mit anderer Zeitzone in einen ungültigen Zustand, und ein Speichervorgang, den die Nutzerin für erledigt hält, läuft ins Leere — bei medizinischen Daten die denkbar unangenehmste Stelle. Der Fehler ist jetzt behoben, und die Lehre daraus ist grundsätzlicher als der einzelne Fix: Zeit gehört intern konsequent in UTC gerechnet und erst an der Oberfläche in die lokale Zone übersetzt, niemals andersherum. Dass ausgerechnet der Ausbau der Abdeckung diesen Fehler ans Licht holte, ist der beste Beleg dafür, dass sich die Mühe rechnet.
Ordnung im Maschinenraum: zentrale Paketverwaltung
Parallel zum Testnetz lief eine Aufräumarbeit, die man von außen nie sieht und im Alltag trotzdem ständig spürt: die Vereinheitlichung der Abhängigkeiten über Central Package Management (CPM). In einer Lösung aus vielen Projekten passiert es sonst schleichend, dass zwei Bausteine unterschiedliche Versionen derselben Bibliothek ziehen — eine hier, eine dort, und irgendwann verhält sich dasselbe Paket an zwei Stellen unterschiedlich. CPM zieht alle Versionsangaben an eine einzige, zentrale Stelle. Es gibt fortan eine Wahrheit darüber, welche Version wovon im Haus ist.
Dazu gehören zwei weitere Bausteine, die zusammen ein rundes Bild ergeben. MinVer liefert eine tag-getriebene Versionierung: Die Versionsnummer eines Builds ergibt sich unmittelbar aus dem Git-Tag, nicht aus einer von Hand gepflegten Zahl in irgendeiner Datei, die man beim Release regelmäßig vergisst. Und gezielte Sicherheits-Pins schließen bekannte Advisories — dort, wo eine transitive Abhängigkeit eine gemeldete Schwachstelle mitbringt, wird die betroffene Version bewusst auf eine sichere festgenagelt, statt zu hoffen, dass schon nichts passiert. Das ist unspektakuläre Hygiene, aber es ist die Sorte Hygiene, die den Unterschied macht zwischen einer Codebasis, die man versteht, und einer, die man nur noch verwaltet.
Dasselbe Szenario, live und lokal
Ein Testnetz ist nur so gut wie seine Nähe zur Wirklichkeit, und deshalb ging es in dieser Phase auch darum, die Tests dichter an den echten Betrieb heranzuführen. Dazu kamen Prod-E2E-Interaktionsmutationen — End-to-End-Tests, die nicht mehr nur Seiten aufrufen und ansehen, sondern gezielt Zustände verändern: etwas anlegen, umschreiben, wieder wegräumen und dabei prüfen, ob die Kette wirklich hält. Ein Test, der nur liest, findet die halben Fehler; erst wer schreibt, stößt an die Kanten, an denen das Zusammenspiel hakt.
Der Baustein, auf den ich dabei am meisten baue, ist eine gemeinsame Szenario-Bibliothek, die dasselbe Szenario live und lokal fährt. Statt zwei getrennte Test-Welten zu pflegen — eine gegen die laufende Produktion, eine gegen die lokale Entwicklungsumgebung — wird ein Szenario einmal beschrieben und in beiden Welten ausgeführt. Das spart nicht nur Arbeit, es schließt eine ganze Fehlerklasse aus: das leise Auseinanderdriften von „so testen wir lokal" und „so verhält es sich in echt". Wenn beide Seiten denselben Ablauf durchlaufen, kann die eine der anderen nicht mehr davonlaufen, ohne dass es sofort auffällt.
Warum sich diese Woche anders anfühlte
Es war keine Woche mit einer glänzenden neuen Funktion, die man vorzeigen kann. Kein neuer Bildschirm, kein Feature zum Anklicken. Und trotzdem war es eine der ruhiger machenden Phasen seit Langem, weil sich unter der Oberfläche etwas Grundlegendes verschoben hat: Qualität hängt jetzt weniger an meiner Tagesform und mehr an einem Mechanismus, der auch dann greift, wenn ich es eilig habe. Ein erzwungenes Coverage-Gate, eine aufgeräumte Paketwelt und ein Testnetz, das seinen Wert am selben Tag bewiesen hat, an dem es entstand — das ist genau die Art unsichtbarer Arbeit, die eine Plattform trägt, statt sie nur zu schmücken.
Was kommt als Nächstes?
Nächste Woche wird es wieder sichtbarer: eine Marketing-Matrix aus 209 Branchen-Feature-Seiten, ein Partner-System und eine neue Über-uns-Seite. Nach diesen Tagen im Maschinenraum freue ich mich darauf, wieder etwas zu bauen, das man sehen und anfassen kann — auf dem Fundament, das jetzt spürbar fester trägt.
Kommentare
Noch keine Kommentare. Teilen Sie als Erste(r) Ihre Gedanken!
Kommentar hinterlassen