Quelle: https://pixabay.com/photos/egg-bird-s-egg-shell-empty-shell-3471439/

Möglichst früh raus aus der Entwicklungsumgebung


19. Juni 2020

Bei modernen Entwicklungsmethoden geht es ja häufig darum, möglichst schnell eine Software-Lösung an echte Anwender auszuliefern. Das bringt nicht nur früheres Feedback, sondern ermöglicht auch einen schnelleren Return on Invest (ROI). Aber natürlich gibt es eine Reihe von mehr oder weniger validen Gründen, warum eine Erstauslieferung doch erst nach einigen Monaten oder gar Jahren erfolgen kann. In diesem Artikel geht es darum, wie man genau in diesem Zeitraum bis zur Erstauslieferung Risiken minimieren kann. In vielen Artikeln geht es darum, den Zeitraum bis zur Erstauslieferung deutlich zu reduzieren – Stichwort Minimum Viable Product (MVP). Obwohl diese Strategien natürlich hochgradig sinnvoll sind, soll dieser Artikel ganz bewusst auf andere Aspekte dieser Problematik fokussieren.

Wenn die Überschrift dieses Artikels lautet „Möglichst früh raus aus der Entwicklungsumgebung“, die frühe Auslieferung an Anwender aber nicht im Fokus stehen soll, dann muss es offensichtlich dazwischen noch etwas geben. Richtig, um dieses „Dazwischen“ soll es hier vornehmlich gehen, nämlich um die Testumgebung, auf der wir die Funktionalität verifizieren bevor wir sie den Anwendern bereitstellen. Und im Verlauf des Textes wird der Leser feststellen, dass das frühe Durchführen von Tests auf dieser Testumgebung nur ein Teilaspekt ist. Viel entscheidender ist, dass das „Möglichst früh raus aus der Entwicklungsumgebung“ auch in den Köpfen des Entwicklungsteams stattfindet.

Ist eine Verkürzung des Zeitraums für die Auslieferung der Software nicht möglich, so lassen sich so auch einige der damit angestrebten Vorteile realisieren, zwar in abgeschwächter Form aber immerhin besser als gar nicht. Wir werden im Weiteren sehen, dass sich hier mit geeigneten Vorgehensweisen auch Feedbackschleifen und darauf basierende Lernerfahrungen und Verbesserungen realisieren lassen. Zwar bekommen wir das Feedback nicht von echten Nutzern, aber es gibt auch eine ganze Reihe technischer Aspekte, die sich so sehr gut abbilden lassen. Es geht hierbei vor allem darum, Annahmen, die während der Entwicklung getroffen wurden, möglichst früh zu verifizieren und unbekannte Risiken möglichst schnell zu erkennen. Den Kern bildet hierbei die Überlegung, dass wir im Entwicklungsprozess Probleme und den aktuellen Qualitätsstand unserer Applikation jederzeit kennen müssen, um in der Entwicklung früh darauf reagieren zu können. Es geht dabei nicht nur um das Ausmerzen von Fehlern, sondern vor allem auch darum, zu erkennen, wie der Prozess und die Vorgehensweise angepasst werden können, um diese Probleme gar nicht erst entstehen zu lassen. Wie können wir problematische Code-Strukturen erkennen und vermeiden? Welche Architekturansätze unterstützen unsere Qualitätsziele? Wie können wir die Zusammenarbeit im Team verbessern und das vorhandene Wissen besser nutzen?

Statt also das Testen als Quality-Gate zu betrachten an dem entschieden wird, ob ein bestimmter Software-Stand den Qualitätsanforderungen entspricht und durchgewunken werden kann, nutzen wir die hier identifizierten Probleme zusätzlich, um den Entstehungsprozess der Software zu optimieren. Es ist mittelfristig wesentlich effizienter, die Qualität in das Produkt einzubauen anstatt zu versuchen diese später in das Produkt reinzutesten. Ganz besonders trifft diese Aussage auf Aspekte wie Performance, Security und Betriebsverhalten zu.

Und damit lösen wir auch gleich noch ein weiteres immanentes Problem der Softwareentwicklung – die Verlässlichkeit von Aussagen bzgl. Fertigstellungsterminen, Budget etc. Diese Termine beziehen sich ja nicht auf den Zeitpunkt, an dem die letzte Zeile Code für den geforderten Funktionsumfang geschrieben wurde, sondern auf einen auslieferfähigen Stand der Software. Wie wollen wir aber zuverlässig abschätzen, wie viele Überraschungen, Probleme und Bugfixes da noch lauern, wenn wir erst mal darauf fokussieren, Funktionen zu implementieren. Je früher wir mit dem realitätsnahen Verifizieren unseres aktuellen Softwarestandes beginnen, desto früher können wir Probleme erkennen und diese beheben und desto verlässlicher werden unsere Aussagen. Wir schaffen quasi ein abgesichertes Fundament, eine stabile Basis, auf der wir die nun folgenden Erweiterungen und Anpassungen aufsetzen. Dabei ist das Ziel natürlich, diese Zyklen wiederum möglichst kurz zu halten.

Es geht also bei „Möglichst früh raus aus der Entwicklungsumgebung“ darum, den aktuellen Entwicklungsstand der Software in einer Umgebung zu testen, die den späteren Produktivbetrieb möglichst gut simulieren kann – und das so früh wie möglich. Klassische Szenarien, die oftmals eher zu einem späten Zeitpunkt im Projekt verifiziert werden, sind beispielsweise:

  • Datenbankmigrationen: In der Entwicklungsphase ist es kein Problem, einen neuen Stand des Datenbankschemas durch Löschen und Neuerstellen der Datenbank herzustellen. Oder das Schema wird gleich während der Entwicklung direkt in der Datenbank geändert. Für einen späteren Produktivbetrieb ist das natürlich keine Option mehr. Hier sollte das Entwicklungsteam möglichst früh Methoden nutzen, die es erlauben, für neue Programmversionen das Datenbankschema zu migrieren – und zwar ohne Datenverlust. Durch den frühen Einsatz von Migrationsstrategien werden diese auch ausreichend erprobt, bevor diese in der Produktivphase dann genutzt werden.
  • Berechtigungen: Auf der Entwicklungsumgebung nutzt man oftmals aus Bequemlichkeit einen Benutzer mit allen Admin-Rechten, um möglichst wenig Probleme zu haben. Für eine Produktivumgebung ist es natürlich sinnvoll, die Dienste und Applikationen mit möglichst eingeschränkten Berechtigungen zu betreiben. Da ist es schon fast vorprogrammiert, dass es im Produktivbetrieb zu unerklärlichem Fehlverhalten kommt, wo doch in der Entwicklungsumgebung alles so gut funktioniert hat. Die in letzter Minute aufgebotenen Quick-Fixes machen die Situation oft noch schlimmer und sind die Ursache für das eine oder andere Security-Problem.
  • Firewall-Einstellungen: Ganz ähnlich verhält es sich auch mit Firewall-Einstellungen. Wird auf der Entwicklungsumgebung die Firewall einfach abgeschaltet um keine Probleme damit zu haben, dann wird es später spannend, welche Ports wie im Produktivbetrieb konfiguriert werden müssen.
  • Systemumgebung: In der Entwicklungsumgebung entsteht die Lösung natürlich inkrementell und damit auch die notwendige Systemumgebung. Hier mal eine kleine Konfiguration, da eine Einstellung oder noch eine kleine Komponente installiert. Bei den vielen Kleinigkeiten verliert man oft den Überblick und dokumentiert wird das Ganze meist auch nur unzureichend. Wie möchte man das nun für die Produktivumgebung schnell und vor allem fehlerfrei reproduzieren? Läuft die Umgebung dann soweit, muss man feststellen, dass irgendwo doch eine Einstellung hart-codiert hinterlegt wurde, weil es da schnell gehen musste und man es später vergessen hat. In solchen Situationen wünscht man sich, man hätte früh in Infrastructure as Code (IaC) investiert und schon in der Entwicklung definierte Umgebungen auf Knopfdruck erzeugt und so deren Funktionsfähigkeit geprüft.
  • Debugging: Zur Analyse von Fehlern während der Entwicklungsphase sind Debugger ein sehr effizientes Werkzeug. Oftmals können diese aber nicht im laufenden Produktivbetrieb genutzt werden. Probleme, die sich nicht in der Entwicklungsumgebung nachvollziehen lassen werden so zu einer Herausforderung. Hier wäre es sicher hilfreich, wenn man in das Produkt verschiedene Analysemethoden wie Logging, Monitoring und Ähnliches eingebaut hätte. Ob die dort gelieferten Informationen allerdings ausreichen, um Fehler schnell einzugrenzen und zu beheben stellt sich erst dann raus, wenn diese Methode aktiv genutzt wird. Deshalb kann es auch sinnvoll sein, auf der Testumgebung kein Remote-Debugging zuzulassen.

 

Was wir bei „Möglichst früh raus aus der Entwicklungsumgebung“ also tun ist, den Ernstfall bereits während der Entwicklung zu trainieren - und das unter möglichst realistischen Bedingungen.

 

Hilfreich dafür ist, beispielsweise sich möglichst früh mit dem Thema Deployment auseinanderzusetzen. Statt sich lange im Projekt mit manuellen Deployments zu begnügen („für die Entwicklung genügt das ja erst mal, die Automatisierung machen wir später“) sollte bereits früh in robuste und reproduzierbare Deployment-Mechanismen investiert werden. Je früher man das tut, desto länger kann man ja auch im Projekt davon profitieren. Beim Deployment sollte auch das Thema Infrastruktur mitberücksichtigt werden – Stichwort Infrastructure as Code. Und diese Deployment-Mechanismen sollten während der Entwicklung konsequent genutzt werden - für das Deployment in die Testumgebung. Damit werden diese Mechanismen auch ständig auf ihre Aktualität geprüft und erprobt. Fühlt sich das zu umständlich an, dann scheint man hier noch Optimierungspotenzial zu haben. Und das Deployment in die Produktivumgebung wird später dann ja nicht besser. Hat man dagegen das Deployment bereits in der Entwicklung vielfach ohne Probleme genutzt, dann sollte auch bei einem Produktiv-Deployment der Blutdruck nicht steigen.

Ideal ist, wenn bereits in der Testumgebung spätere Produktivsituationen berücksichtigt werden. Z.B. sollte der Frage, wie lange ein solches Deployment dauert und wie der Rollback für ein missglücktes Deployment aussieht, ausreichend Beachtung geschenkt werden. Wie lange muss das System offline genommen werden, um eine neue Version einzuspielen? Werden unsere Anwender diese Downtimes akzeptieren? Können wir hier bessere Mechanismen nutzen?

Natürlich steigt die Aussagekraft unserer Überprüfungen mit der Realitätsnähe. Dafür ist es auch sinnvoll, ein wenig Zeit in eine Art von Simulation zu investieren. Wie können wir z.B. nach dem Ausrollen einer neuen Version in das Testsystem deren Funktionsfähigkeit schnell sicherstellen? Da sind automatisierte Tests gut investierte Zeit – welche Art und in welchem Umfang hängt dabei von der jeweiligen Situation ab. Auch eine gewisse Benutzerlast zu simulieren kann hilfreich sein, um Laufzeitverhalten zu verifizieren. Wie verhält sich das System, wenn auch eine größere Menge von Daten im System erfasst ist? Funktioniert unser unterbrechungsfreies Update wirklich? Mit nur wenig Aufwand lassen sich „virtuelle Benutzer“ simulieren, kleine Automatismen, die bestimmte Benutzeraktionen ausführen und damit die Nutzung des Systems simulieren können. Automatisierte Verifikation lässt sich durchaus auch so implementieren, dass diese auch später im Produktivbetrieb genutzt werden kann. So kann eine neu ausgerollte Version nicht nur sehr schnell auf Probleme geprüft werden, sondern diese können auch im laufenden Betrieb genutzt werden, um Systemausfälle oder andere Probleme schnell zu detektieren – idealerweise noch vor dem ersten Anwender.

All das sind Dinge, mit denen sich ein Entwicklungsteam frühzeitig auseinandersetzen sollte. Die Erkenntnisse, die hierdurch gewonnen werden, sind im Entwicklungsprozess sehr wertvoll und am Ende des Projektes reicht die Zeit eh nicht mehr, solche Methoden noch umzusetzen, ganz zu schweigen davon, die dann erkannten Defizite zu beseitigen.

Fazit

„Möglichst früh raus aus der Entwicklungsumgebung“ ist in erster Linie ein Mindset-Thema. Hier geht es darum, dass das Entwicklungsteam sein Software-Produkt für den Produktivbetrieb designen möchte und die Wirksamkeit der dafür getroffenen Entscheidungen natürlich auch frühzeitig überprüfen möchte. Nur, wenn man sich für die Risiken in einem späteren Live-Betrieb interessiert, lassen sich diese auch schon frühzeitig in der Entwicklung erkennen und eliminieren. Wenn man davon ausgeht, dass es später eh das Problem einer anderen Abteilung sein wird, dann bleiben diese Effekte natürlich begrenzt. Nutzt ein Entwicklungsteam die hier beschriebenen Methoden aber konsequent, so wird sich innerhalb kurzer Zeit ein Lerneffekt einstellen, der das Team befähigt, schneller und effizienter robuste und wirklich einsatzfähige Software zu erstellen. Und das kommt wiederum der Vorhersagbarkeit und der Transparenz zugute, so lange die Indikatoren ernst genommen werden und nicht mit schnellen Workarounds vertuscht werden. Das Team kann so besser verstehen, wie es im Entwicklungsprozess bereits die richtigen Weichen für einen stabilen Betrieb stellt.

Damit das umgesetzt werden kann, darf der Lieferdruck auf das Entwicklungsteam natürlich nicht zu hoch sein. Ein Team, das seine vollständige Kapazität aufwenden muss, um die gewünschte Funktionalität umzusetzen, wird keine Möglichkeit haben, in die Zukunft zu investieren und Maßnahmen wie die hier beschriebenen umzusetzen. Das ist kurzsichtig und die Auswirkungen werden alsbald spürbar sein. Von einem professionellen Entwicklungsteam kann man aber auch erwarten, dass es die Umsetzung von Strategien zu Risikominimierung einfordert und deren Nutzen klar herausstellt.

 

Risiken und Probleme frühzeitig zu erkennen und zu eliminieren macht uns nicht langsamer, im Gegenteil sind die meisten Projektverzögerungen darauf zurückzuführen, dass Probleme zu lange aufgeschoben wurden.

 


Sie finden das Thema spannend und möchten mehr darüber erfahren? Vielleicht ist das Applying Professional Scrum for Software Development Training für sie interessant?

Oder sie vereinbaren einen Termin zu einem kostenlosen und unverbindlichen Gedankenaustausch.

Termin vereinbaren
Impressum: Thomas Schissler (Einzelunternehmer) | agileMax
Mühlhäule 3 | D-89134 Blaustein | eMail: info@agileMax_Website.de | Tel: +49 7304 918209-0
USt-IdNr.: DE 321547962 | Datenschutzerklärung