Blog
Teil 3 von 3 The Pragmatic Programmer

Teams und Automation

6 min Lesezeit
bücher software-craft pragmatic-programmer

Stefan hatte ein Word-Dokument. 23 Schritte, mit Screenshots. Schritt 7: “Cache invalidieren (siehe Confluence-Seite ‘Cache Management’, Link funktioniert nur im VPN).” Schritt 14: “Warten bis der Health Check grün wird. Wenn nach 3 Minuten noch rot, Schritt 11 wiederholen aber diesmal mit dem Flag --force-recreate.” Schritt 19: “Martin fragen ob die Downstream-Consumer neu gestartet werden müssen.”

Stefan konnte das Deployment fehlerfrei durchführen. Stefan alleine. Wenn Stefan im Urlaub war, wurde nicht deployed. Wenn Stefan krank war, wurde nicht deployed. Wenn Stefan mittags beim Döner war und ein Hotfix rausmusste, hat das Team gewartet.

Das ist kein Prozess. Das ist eine Geiselnahme.

Die Person die alles weiß

Hunt und Thomas schreiben im letzten Kapitel über pragmatische Teams. Aber das was bei mir hängen geblieben ist, steht zwischen den Zeilen: die gefährlichste Person in deinem Team ist nicht die schwächste. Es ist die stärkste.

Ich hatte einen Kollegen, Java-Backend, der drei Spring-Boot-Services alleine hochgezogen hat. Sauber gebaut, ordentliche Test Coverage, durchdachte Hexagonal Architecture. Code Reviews? “Verlangsamt mich nur.” Pair Programming? “Ich erklär’s euch wenn’s fertig ist.” Wissen teilen? “Steht doch im Code.”

Er hat gekündigt. An einem Mittwoch. Zwei Wochen Kündigungsfrist.

Danach hatten wir drei Services, die niemand anfassen konnte. Der Payment-Reconciliation-Service hatte eine Custom DSL für Abrechnungsregeln, die nur Sinn ergab wenn man wusste warum er bestimmte Architekturentscheidungen getroffen hatte. Das stand nirgends. Nicht in den Commits, nicht in einem ADR, nicht in Confluence. Es stand in seinem Kopf, und sein Kopf war jetzt bei einem anderen Arbeitgeber.

Sechs Monate haben wir gebraucht, um diese Services wieder under control zu kriegen. Sechs Monate.

“Quality is a team issue.”

Stimmt. Aber nicht so wie man denkt. Qualität heißt nicht, dass jeder im Team guten Code schreibt. Qualität heißt, dass das Team als Ganzes funktioniert, wenn eine einzelne Person morgen weg ist.

Automate Everything (naja, fast)

“Don’t use manual procedures.”

Stefans Word-Dokument hätte nie existieren dürfen. Das ist die Aussage von Hunt und Thomas, und in 90% der Fälle haben sie recht. Jeder manuelle Schritt ist eine Fehlerquelle. Um drei Uhr nachmittags, nach dem dritten Deployment des Tages, vergisst du den Cache zu invalidieren. Oder du führst das Migration-Script gegen Staging statt Prod aus. Oder umgekehrt. Beides schlecht.

Build: ein Befehl. Tests: bei jedem Push automatisch. Deployment: ein Knopf, Rollback ein zweiter. Infrastruktur: Terraform, nicht “ich hab das mal in der AWS Console geklickt.”

Aber.

Hunt und Thomas haben das 1999 geschrieben. Die Welt war eine andere. Und der Satz “automate everything” wird in manchen Teams zum Dogma, das mehr Schaden anrichtet als Stefans Word-Dokument.

Ich hab ein Dreierperson-Team gesehen, das drei Wochen in eine Terraform-Pipeline investiert hat, die sie zweimal im Jahr benutzen. Die alte Methode: einer logged sich in die Console ein, klickt vier Buttons. Dauert 10 Minuten. “Aber es ist nicht automatisiert!” Richtig. Es muss auch nicht.

Automation lohnt sich wenn: der Prozess häufig ist, fehleranfällig, und mehr als eine Person betrifft. Stefans 23-Schritte-Dokument? Sofort automatisieren. Das jährliche SSL-Zertifikat-Renewal das drei Klicks braucht? Ein Runbook im Wiki reicht. Der Aufwand, das zu automatisieren, ist größer als der Aufwand, es dreimal manuell zu machen.

Pragmatisch heißt nicht automatisch. Pragmatisch heißt: den richtigen Aufwand an der richtigen Stelle.

Wo die Bugs wirklich leben

“Test your software, or your users will.”

Ich sollte mir den Satz über den Monitor hängen. Aber das ist nicht die Stelle die mich zum Nachdenken gebracht hat. Das hier ist sie:

Wir hatten zwei Services. Order-Service, Go. Billing-Service, Java. Der Order-Service schickt eine Bestellung an Billing. Feld quantity, der Order-Service schickt es als String: "3". Der Billing-Service erwartet einen Integer: 3. Auf beiden Seiten: perfekte Unit Tests. Order-Service testet, dass er das richtige JSON baut. Billing-Service testet, dass er eine Bestellung korrekt verarbeitet.

100% grün. Alles kaputt.

Weil kein einziger Test geprüft hat, was passiert wenn die beiden Services miteinander reden. Der Contract zwischen den Services — das Feld quantity, sein Typ, sein Format — existierte nur als implizite Annahme. Auf der einen Seite: “ist halt ein String, JavaScript-Erbe.” Auf der anderen Seite: “ist offensichtlich ein Integer.” Offensichtlich. Bis Produktion.

“Design to test.”

Hunt und Thomas meinen damit: Code der schwer zu testen ist, ist schlecht designed. Stimmt. Aber ich geh weiter. Das eigentliche Testproblem in den meisten Teams sind nicht fehlende Unit Tests. Es sind fehlende Integration Tests. Fehlende Contract Tests. Fehlende Tests an den Grenzen, wo zwei Systeme aufeinander treffen.

Meine Regel seit dem quantity-Desaster: teste die Nahtstellen. Nicht die Logik innerhalb eines Service, die ist meistens offensichtlich, und wenn sie es nicht ist, hast du ein anderes Problem. Sondern die Stellen wo System A eine Annahme über System B macht. Da leben die Bugs. Da explodiert Freitagabend die Produktion.

Ein Contract Test für das quantity-Feld hätte 20 Minuten gedauert. Die Produktionsstörung hat vier Stunden gekostet plus ein Postmortem plus ein Stakeholder-Call am Montag.

Broken Windows im Team

“Teams as a whole should not tolerate broken windows.”

Kennst du aus Kapitel 1, die Broken-Windows-Theorie. Auf Team-Ebene wird sie erst richtig gefährlich.

Irgendwann hat ein Entwickler in unserem Team angefangen, Tests zu skippen. Nicht böswillig. Zeitdruck, Sprint-Ende, “schreib ich morgen.” Morgen wurde nächste Woche. Nächste Woche wurde nie. Und dann hat der nächste Entwickler gesehen, dass PRs ohne Tests durchgehen. Und der nächste. Nach drei Sprints: Coverage von 78% auf 41%. Nicht weil alle absichtlich aufgehört haben zu testen. Sondern weil ein Signal im Raum stand — Tests sind hier optional.

Team-Kultur ist nicht was im Confluence-Wiki steht. Team-Kultur ist was passiert wenn Zeitdruck kommt.

Schluss

Das Buch endet mit einem Appell. Hunt und Thomas fragen, was für ein Entwickler du sein willst.

Ich finde die Frage falsch gestellt. Es geht nicht um Haltung oder Leidenschaft oder ob du “dein Handwerk ernst nimmst.” Es geht um Gewohnheiten. Schreibst du den Test oder nicht. Automatisierst du das Deployment oder lässt du es bei Stefans Word-Dokument. Sprichst du das Problem an oder hoffst du dass es jemand anders tut.

Die Antwort ist nicht einmal. Die Antwort ist jeden Tag.

Das war die Serie. Das Buch ist von 1999 und immer noch relevanter als die meisten Conference Talks die ich dieses Jahr gesehen hab.