Bevor Sie anfangen, den Release-Zyklus zu verkürzen, sollten Sie erstmal in der Lage sein, regelmäßig zu liefern. Die häufig vorkommenden Probleme und praktikable Lösungsmöglichkeiten haben wir hier zusammengestellt.
Um es klar zu sagen: mit Liefern meinen wir die Auslieferung in den Produktivbetrieb, nicht etwa nur “Diese Iteration ist fertig und abgenommen”. Und regelmäßig heißt: in einem festen Rhythmus, also z.B. ein Release alle 4 Wochen, so dass die nächsten Release-Termine absolut vorhersehbar sind.
Schon die erste Umsetzung der Features dauert länger als erwartet, da muss eben das Release warten, bis alle versprochenen Features (oder Bugfixes, oder sonstigen Anforderungen) fertig sind. Vielleicht erleben Sie auch diese Variante: Wir merken im Laufe des Releases, dass wir nicht fertig werden. Dann verhandeln wir über eine Verringerung das Scopes. Aber auch nachdem wir depriorisiert haben, werden wir innerhalb des geplanten Release-Zeitraums nicht fertig.
Machen Sie den Release-Termin zum Feature Nummer 1. Die fertigen Features verdienen es nämlich, so früh wie möglich in Produktion zu kommen.
Geben Sie Schätzungen statt Versprechen ab. Sagen Sie: “Wir schätzen, dass wir Features A, B, C und D im nächsten Release fertig haben” statt: “Das nächste Release wird A, B, C und D enthalten”. Dahinter steht der Gedanke, den Scope variabel zu machen:
Die gesamte Unsicherheit der Schätzung wird im Faktor Scope konzentriert, damit man bei den anderen drei Faktoren verlässliche Zusagen machen kann.
Oft wird der Release-Termin auch geopfert, weil einige Features noch nicht ganz fertig sind. Sie haben also z.B. zum geplanten Release-Termin nur 5 von 10 Features fertig. Die restlichen fünf hängen alle irgendwo zwischen 80% und 100%, etwa so:
Also wollen Sie “noch ein bißchen mit dem Release warten”, statt nur die ersten 5 Features auszuliefern. Daraus werden leicht wochenlange Verzögerungen, weil immer etwas anderes schief geht. Unter Zeitdruck (wir sind ja spät dran mit dem Release) werden Kompromisse bei der Qualität oder der Vollständigkeit gemacht.
Bearbeiten Sie weniger Dinge gleichzeitig, dann gibt es auch weniger unfertige Features. Die Anzahl an unfertigen Features zu begrenzen, entspricht dem Lean-Prinzip: Limit WIP (work in process). Im obigen Beispiel könnten Sie mit demselbenn Arbeitsaufwand etwa 9 von 10 Features zum geplanten Release-Termin fertig haben (100%):
In der Umsetzung dieses Ratschlags werden Sie merken, dass Sie auf substanzielle (d.h. auch schwierige) Verbesserungen in Ihrem Software-Lieferprozess stoßen. Dafür werden Sie u.a. mit besserer Qualität belohnt.
Unfertige Features (WIP) entsteht auch durch das Arbeiten in großen Stapeln (Batches). So wird manchmal zunächst alles entwickelt, gefolgt von einer Test-und-Fix-Phase, die alle Features gemeinsam durchlaufen. Diese Phase findet natürlich erst gegen Ende des Release-Zyklus statt. Zerlegen Sie besser das Release in mehrere kleinere Stapel, oder testen Sie ein Feature gleich im Anschluss an die Entwicklung. Noch besser (aber schwieriger): entwickeln Sie automatisierte Akzeptanztests vor der eigentlichen Implementation.
Man könnte natürlich auch versuchen, das Problem “Es dauert immer wieder länger als gedacht” zu bewältigen, indem man zuverlässiger schätzt. Manchmal können Sie Unterschätzungen vermeiden, indem Sie das Feature in kleinere Einheiten zerlegen. Insgesamt ist zuverlässig schätzen ziemlich aufwändig, weswegen einige Teams auf Schätzungen ganz verzichten, oder nur grobe Skalen wie T-Shirt-Größen (S, M, L, XL) benutzen.
In Scrum werden unzuverlässige Schätzungen kompensiert, indem in festen Timeboxes gearbeitet wird (ein Sprint), an deren Ende potenziell lieferbare Software steht. Die Menge an unfertigen Features (WIP) ist im Wesentlichen begrenzt auf den Inhalt einer Iteration. Man kann sich auch nur maximal um den Aufwand für eine Iteration verschätzen.
Kanban bzw. Lean Software Development begrenzt WIP in allen Phasen der Entwicklung. Der “Überhang” an unfertigen Features kann dann nicht größer werden als die Summe der WIP-Limits in den relevanten Phasen. Kanban legt einen Schwerpunkt auf den gleichmäßigen Fluß (flow) von Features durch den Entwicklungsprozess. Wenn das richtig gemacht wird, ist man quasi jederzeit Release-fähig; man liefert zum Termin das, was fertig ist. Vorhersagen zum Inhalt des Releases kann man anhand von Statistiken zur Durchlaufzeit machen.
Was ist, wenn einige Features einfach objektiv länger dauern als der Release-Zyklus?
Versuchen Sie zunächst, das Feature kleiner zu machen. Man kann z.B. einzelne User Stories erst ein Release später machen. Oder Teile der Geschäftslogik, wie etwa Rabattberechnung, in eine Engine auslagern. Im ersten Release wird dann der Rabatt nur für die einfachen Fälle berechnet, aber das Drumherum (Anzeige des Rabatts, Besteuerung) kann schon fertig sein. Die komplizierteren Rabattberechnungen kommen ein Release später.
Wenn das Feature dann immer noch zu groß ist, helfen Feature Switches. Das heißt, man macht ein ganzes Feature per Konfiguration an- und abschaltbar. Auch ein unfertiges Feature kann dann ausgeliefert werden, es ist nur abgeschaltet. Für Tests, und um Feedback einzusammeln, kann man das Feature für einzelne User oder auch zeitweise aktivieren. Je kürzer Ihre Release-Zyklen werden, desto wichtiger ist es, solche Abschaltmöglichkeiten zu haben.
Verringern Sie die Ende-zu-Ende Zeit für die Entwicklung des Features. Es ist eher unwahrscheinlich, dass der Entwickler derzeit 40 Stunden die Woche an diesem Feature arbeitet. Versuchen Sie, die Unterbrechungen zu minimieren, es sollte also keine weiteren Aufgaben neben dem großen Feature geben. Wartezeiten, z.B. auf Feedback aus der Fachabteilung, oder Testergebnisse, sollten für solche langlaufenden Features offensiv verringert werden.
Schließlich können Sie die Parallelität der Abarbeitung erhöhen, also mehrere Leute gleichzeitig an demselben Feature arbeiten lassen. Wenn Sie Sorge wegen des Koordinations-Aufwandes haben, können Sie zwei Entwickler mit pair-programming arbeiten lassen.
“Ein schwerwiegender Bug hat sich im Produktivbetrieb gezeigt, das muss unbedingt noch behoben werden.” Oder “Wir haben da diese neue Kooperation, im Vertrag steht, dass wir die entsprechenden Anpassungen am Webshop in zwei Wochen fertig haben.” Solche Prioritätsverschiebungen in letzter Minute können den besten Release-Plan über den Haufen werfen.
Scrum ist da ganz rigoros: Wir fixieren am Anfang der Iteration (Sprint), was gemacht werden soll. Wer nach dem Start der Iteration ein neues Feature X haben will, hat zwei Optionen: (1) Sich bis zur nächsten Iteration gedulden, oder (2) die laufende Iteration abbrechen und mit Feature X eine neue Iteration starten.
Eine Option (3) – wir schieben Feature X irgendwie dazwischen – gibt es nicht, egal wieviel Druck in dieser Richtung aufgebaut wird. Meist kühlen sich die Gemüter dann schnell ab, man geduldet sich noch etwas, weil Option (2) zu drastische Auswirkungen hätte.
Genauso können Sie es natürlich auch mit einem Release halten: “Nichts geht mehr”, den Relase-Termin zu halten, ist wichtiger als Feature X.
Die weichere Variante dazu: bieten Sie an, das neue Feature gegen ein oder mehrere andere auszutauschen. Machen Sie ganz klar, welche Kosten damit verbunden sind: “OK, wir könnten Feature X noch in diesem Release machen. Dafür müssten wir Features A und B opfern. Der bisherige Aufwand für A und B wäre so gut wie verloren, weil sich die Entwickler im nächsten Release wieder quasi von vorn einarbeiten müssen. Sollen wir das wirklich so machen?” Für solche Diskussionen ist es natürlich hilfreich, wenn Sie eine visuelle Übersicht zum Inhalt des Releases zur Hand haben, z.B. ein Kanban-Board.
Gehen Sie den Ursachen für dringende Last-Minute Anforderungen nach. Warum wird oft soviel Druck gemacht? Können die Leute mit ihren Wünschen nicht bis zum nächsten Release warten? Es kann einfach daran liegen, dass Ihre Release-Zyklen so lang sind. Wenn Sie z.B. nur alle drei Monate liefern, wird jede Anforderung automatisch um mindestens drei Monate verzögert. Wenn Sie dagegen jede Woche liefern, fällt es leichter, sich noch etwas zu gedulden. Wenn ich die U-Bahn in Hamburg verpasse, ist das meist nicht so schlimm: in 5 Minuten kommt die nächste. Aber wehe, wenn ich den Flug von Rostock Laage nach Teneriffa verpasse: der geht nur einmal pro Woche.
Woher kommen die unerwarteten Anforderungen? War es ein Bug, der z.B. im vorigen Release eingebaut wurde? Dann sollten wir z.B. in Regressionstests investieren. Oder war es eine Anforderung, die wir einfach nicht auf dem Zettel hatten, als wir das Release planten? Dann waren eventuell nicht alle relevanten Stakeholder bei der Planung vertreten, oder wir haben uns nicht genug Beispiele geben lassen.
Kanban bzw. Lean Software Development behandelt Last-Minute Anforderungen so: Idealerweise ist der Software-Lieferprozess stabil, d.h. man kann Zusagen machen wie: “95% der Anforderungen brauchen bei uns weniger als 10 Tage, bis sie produktionsreif sind”. Meist reicht das – wenn der Release-Termin erst in 14 Tagen ist, starten wir Feature X morgen und sind ziemlich sicher, dass es im Release landen wird.
Wenn diese Zusagen nicht ausreichen, kann man eine gesonderte Überholspur (Priority Lane) im Kanban-Board einrichten. Sobald ein Feature auf der Überholspur ist, wird es bevorzugt bearbeitet. Im Extremfall können Sie die Regel aufstellen, dass ein Feature auf der Überholspur alle Arbeiten in dieser Phase unterbrechen kann. Etwa so wie ein alle Autos anhalten müssen, sobald ein Krankenwagen mit Blaulicht vorbeifahren will. Für die Überholspur ist es besonders wichtig, ein WIP-Limit einzurichten, damit die übrige Arbeit nicht total chaotisch wird. So kann man etwa sagen, dass es nur maximal zwei Tickets auf der Überholspur geben darf, über alle Phasen der Software-Lieferung hinweg.
Wenn es häufig solche Last-Minute Anforderungen gibt, verschlechtert sich die Durchlaufzeit der übrigen Anforderungen – wenn einer in der Warteschlange vordrängelt, müssen alle anderen etwas länger warten. Die regelmäßige Evaluierung der Durchlaufzeiten ist im Kanban-Prozess eingebaut, sie wird dieses Problem früher oder später offensichtlich machen. Das sollte dann den Anstoß geben, die Last-Minute Anforderungen durch kontinuierliche Verbesserung zurückzudrängen.
“So kann das nicht rausgehen” – mal wieder zeigen sich gravierende Probleme bei einem Feature, das wir eigentlich für fertig gehalten hatten. Das können Bugs sein, oder Performance-Probleme, oder Missverständnisse bei der Spezifikation. Was auch immer, jetzt müssen wir nacharbeiten, und das gefährdet den Release-Termin, ganz zu schweigen von dem zusätzlichen Stress für das Team.
Machen Sie das Release unabhängig von einzelnen Features. Der Release-Termin ist Feature Nummer 1, er sollte nicht von einem einzelnen Feature über den Haufen geworfen werden können. Nutzen Sie daher Feature-Switches, d.h. Konfigurationseinstellungen, die ein ganzes Feature an- und abschaltbar machen. So können Sie immer noch in letzter Minute die Reißleine ziehen und das unfertige Feature im Release verbergen.
Verlegen Sie die bösen Überraschungen nach vorne. Sobald ein Feature “fertig entwickelt” ist, machen Sie die nötigen Tests. Demonstrieren Sie es dem Fachbereich, um Feedback zur Funktionalität zu bekommen. Bauen Sie regelmäßig das Gesamtsystem zusammen und machen Sie Regressionstests darauf.
Überdenken Sie Ihre “Definition of Done” – ein Feature ist erst fertig, wenn es die Regressionstests bestanden hat, wenn es ein Demo beim Fachbereich gab usw. Wenn das Feature also in diesem Sinne wirklich “Done” ist, sollten die meisten bösen Überraschungen schon hinter uns liegen.
Setzen Sie eine Grenze für die Anzahl an unfertigen Features (WIP limit). Damit wird das Team dazu angehalten, erstmal die späteren Phasen abzuschließen, bevor ein neues Feature angefangen wird.
Eine vereinfachte Variante, die nicht ganz so effektiv ist: Ab einem bestimmten Zeitpunkt, z.B. nach 2/3 des Release-Zyklus, nichts Neues mehr anfangen, also einen “Feature Freeze” ausrufen. Damit beenden Sie den Zufluss in den Entwicklungsprozess und gewinnen Spielraum, um sich den bösen Überraschungen zu widmen. Wenn der Zeitpunkt richtig gewählt ist, werden Sie gelegentlich “Leerlauf” haben, d.h. es gibt gerade keine aktuelle böse Überraschung, aber es könnten weitere in unregelmäßigen Abständen folgen. Nutzen Sie diese Zeit für kontinuierliche Verbesserungen, um zukünftige Überraschungen zu verhindern. Sie können etwa automatisierte Lasttests schreiben, oder das Aufsetzen von Testumgebungen vereinfachen u.ä. Wenn dann eine Überraschung kommt, sollten Sie alles stehen und liegen lassen und sofort reagieren.
Gehen Sie den Überraschungen auf den Grund und beheben Sie die Ursachen. Natürlich müssen wir zunächst das akute Problem lösen, also z.B. den Bug fixen. Entscheidend ist, was danach kommt: wenn wir jetzt nicht die Ursachen der Überraschung angehen, wird ein ähnliches Problem im nächsten oder übernächsten Release wieder auftreten.
Fragen Sie also: Was waren die tiefergehenden Ursachen für diese Überraschung? Wie hätten wir das verhindern können? Investieren Sie auf der Stelle etwas Kapazität in die Behebung der Ursachen.