Qualität ist Teamwork

Keine Kommentare

Wir werden oft zu Projekten hinzugezogen, in denen ein hohes Maß an Softwarequalität gefragt ist. Seien es große Legacy-Anwendungen mit Qualitätsproblemen, bei denen das Kind schon in den Brunnen gefallen ist, oder junge Pilotprojekte, die auf ein stabiles Fundament gebaut werden sollen. Als erfahrene technische Experten können wir in diesen Fällen grundsätzlich weiterhelfen. Kunden ist aber anfangs oft nicht klar, dass Qualität auf mehr beruht als nur guter Technik.

Selbst technisch exzellente Teams können in Qualitätsprobleme geraten, wenn die Rahmenbedingungen nicht stimmen oder das Ziel unklar ist. Warum das so ist, und wie man gegensteuern kann, erläutern wir im Folgenden.

Qualitätsprobleme durch Bugs

Qualitätsprobleme machen sich für das Management oft erst dann wirklich bemerkbar, wenn die Fehlerzahl inakzeptabel ansteigt. Doch was ist überhaupt ein Bug und was nur ein (fehlendes) Feature? Dies führt regelmäßig zu Diskussionen zwischen Produktverantwortlichen und Entwicklung und kann streng genommen ohne klar dokumentierte Spezifikation gar nicht beantwortet werden.

Wie kann während der Entwicklung entschieden werden, was „weg kann“ und was definitiv noch funktionieren muss? Schnell wird ein Bug gefixt und zehn neue entstehen, sobald in der neuen Version etwas nicht mehr so funktioniert „wie vorher“. Aus Angst, etwas kaputtzumachen, bleiben dann auch mal ohne Not Altlasten im Code und verringern die Wartbarkeit immer weiter.

Um aus diesem Dilemma herauszukommen, braucht es ein gemeinsames Verständnis davon, was die Software eigentlich ist, was sie kann und was nicht. Zu jeder User Story gehören klare Akzeptanzkriterien und ggf. auch eine Abgrenzung, was explizit nicht dazugehört. Das schließt auch ein klares Verständnis des „Warum?“ ein, also welchen konkreten Nutzen ein bestimmtes Feature bringt. Erfahrene Teams vermeiden durch diese Kommunikation Bugs schon vor dem eigentlichen Programmieren.

Die Entwicklung muss dann natürlich auch in der Lage sein, die Anforderungen technisch einwandfrei zu implementieren und durch Tests abzudecken. Hierbei helfen z. B. Pair Programming, Code Reviews und testgetriebene Entwicklung (TDD).

Tests

Wir finden oft Projekte mit unzureichender Testabdeckung vor. Unser Ansatz ist es, keinen neuen Code zu schreiben und keinen Bug zu fixen, ohne dafür automatisierte Tests vorweisen zu können. Dies setzt wieder voraus, dass klar ist, was die Software eigentlich tun soll. Die Akzeptanzkriterien können als Grundlage für automatisierte Tests dienen. Der Ansatz der aktzeptanztestgetriebenen Entwicklung geht sogar so weit, dass die Spezifikation selbst als ausführbarer Test implementiert wird. Ebenso muss bei Bugs deutlich beschrieben sein, welches Verhalten eigentlich vom Soll abweicht und wie sich der Fehler reproduzieren lässt. Mit diesen Informationen können dann entsprechende Testfälle nachgebildet und Regressionen vermieden werden.

Hier ist es wichtig, dass das Unternehmen hohe Testautomatisierung als wesentlichen Bestandteil hochwertiger Softwareentwicklung versteht, der die Entwicklung tatsächlich schneller macht. Die Entwicklungszeit muss stets auf Basis funktionierender Features gemessen werden. Um diese Botschaft verständlich zu machen, reicht ein Einsatz technischer Expert*innen nicht aus, sondern es braucht eine kulturelle und organisatorische Veränderung, die je nach Unternehmen bis zur Geschäftsleitung reichen muss. Die Entwicklungsteams können solch eine Veränderung nicht von alleine bewerkstelligen.

Außerdem kann man eine effiziente Testautomatisierung nur erreichen, wenn Softwareentwickelnde und Testende cross-funktional zusammenarbeiten. Wenn das Testing nachgelagert wird (z. B. durch eine dedizierte QA-Abteilung), verliert man viele Vorteile der Testautomatisierung, wie zum Beispiel schnelle Feedbackzyklen. Daher gehen organisatorische Themen, wie z. B. Teamstrukturen und Abläufe, häufig Hand in Hand mit technischen Themen.

Es reicht aber umgekehrt nicht, gute Anforderungsdokumente zu liefern und auf eine neue Kultur zu pochen. Teams müssen in der Lage sein, die Anforderungen in einer effizienten Testpyramide abzubilden und sicherzustellen, dass die Funktionen auch in einigen Monaten noch funktionieren. Auch die praktische Zusammenarbeit in cross-funktionalen Teams muss gelernt werden.

Außerdem hängt die Testbarkeit sehr stark von der Codequalität ab. Technische Methoden wie Test-driven Development und Refactorings können helfen, die Testbarkeit zu erhöhen. Mit erfahrenen Entwickler*innen oder Coaches können diese Methoden leichter etabliert werden.

Refactorings

Legacy-Anwendungen leiden oft darunter, dass alter Code nur sehr schwer verständlich und wartbar ist. Neue Features werden dadurch extrem teuer und die Bugrate steigt.

Erfahrene Teams refaktorieren ihre Anwendung kontinuierlich und lassen es im Idealfall erst gar nicht so weit kommen. Sie sind in der Lage zu erkennen, wie man das Software-Design verbessern kann, um das aktuelle Feature einfacher umzusetzen, und wechseln regelmäßig die „zwei Hüte“ (neue Funktionalität und Refactoring), um ihre Ziele zu erreichen. Sie behalten im Blick, dass das technische Fundament für die kommenden Anforderungen optimal gewappnet ist. Dazu müssen sie sich kontinuierlich mit den Produktverantwortlichen austauschen und die fachlichen Ziele verstehen.

Doch was, wenn große Refactorings dennoch notwendig werden? Rein technisch fokussierte Teams würden gerne keinen Stein auf dem anderen lassen oder eine Anwendung sogar komplett neu schreiben. Das ist aber selten die effizienteste Anwendung knapper Kapazitäten.

Refactorings sollten immer darauf einzahlen, zukünftige Features schneller umsetzen zu können. Dazu muss man aber wissen, in welche Richtung sich die Anwendung zukünftig entwickeln soll. Eine klare Produktvision und strategische Ausrichtung auf bestimmte Ziele ist nötig, damit Refactorings da eingesetzt werden können, wo sie tatsächlichen Wert schaffen.

Ob man größere Refactorings angehen soll, ist eine Ermessensentscheidung, die man selten aus rein technischen Gründen treffen kann. Wenn man eine klare Produktstrategie hat, die wichtige Rahmenbedingungen setzt, hilft das enorm, den relativen Aufwand einzuschätzen. Damit können wichtige Fragen beantwortet werden, z. B.

  • Inwiefern wird diese Komponente in nächster Zeit erweitert?
  • Erfüllt das aktuelle Software-Design die Anforderungen, die auf der Produkt-Roadmap stehen?
  • Müssen wir (im schlimmsten Fall) in nächster Zeit diese Komponente komplett wegwerfen oder neu bauen?

Die beste Produktvision kann jedoch nicht umgesetzt werden, wenn Teams nicht in der Lage sind, „den Karren aus dem Dreck zu ziehen“. Wenn klar ist, wohin die Reise gehen soll, braucht es geschulte Leute, die eine Legacy-Anwendung gezielt in diese Richtung refaktorieren können.

Architektur

Software-Architektur ist kein Selbstzweck, sondern dient dazu, den geschäftlichen Anforderungen den optimalen technischen Unterbau zu bieten. Es gibt nicht „die beste“ Architektur, sondern es geht immer darum bestimmte Trade-offs einzugehen. Verschiedene Architekturziele können sich widersprechen und müssen gegeneinander abgewogen werden. Dabei müssen die funktionalen Anforderungen mit einbezogen werden. Für eine zweckmäßige Architektur ist also auch wieder das Produktziel entscheidend.

Dennoch stößt man immer wieder auf einen Konflikt zwischen aktuellen und zukünftigen Anforderungen. Einerseits soll die Architektur evolutionär sein und inkrementell verbessert werden. Schließlich kann man das Feedback der Nutzer*innen und die zukünftigen Prioritäten nicht vorhersagen. Andererseits müssen bestimmte Architekturentscheidungen früh getroffen werden und das richtige Fundament kann die zukünftige Entwicklung erleichtern. Nur ein gut funktionierendes Team, welches das relevante technische und fachliche Wissen zusammenbringt und die Verantwortung für die Architektur übernimmt, ist in der Lage, die richtigen Entscheidungen zu treffen und optimal auf Veränderungen zu reagieren.

Nur durch diese Zusammenarbeit ist es möglich, die richtigen fachlichen Schnitte der Anwendung zu identizifieren und die Business-Domäne und deren Objekte zu definieren. Wichtig ist auch eine einheitliche Sprache, damit solche Objekte und die Use-Cases der Software von allen klar verstanden sind.

Teams müssen im Tagesgeschäft über Architektur diskutieren und mit verschiedenen Lösungsmöglichkeiten experimentieren können. Dies funktioniert nicht in Organisationen, in denen Arbeitspakete „von oben“ zugewiesen werden und ein hoher Stresslevel durch fremdbestimmte Deadlines existiert. Agiles Arbeiten in selbstorganisierten Teams ist daher eine wichtige Voraussetzung für gute Architekturentscheidungen.

Es reicht aber auch nicht aus, Agilität einzuführen und darauf zu hoffen, dass die Teams ab sofort gute Architektur umsetzen. Dies wird nicht funktionieren, insbesondere, wenn vorher ein anderes Arbeitsklima vorherrschte und daher keine Übung in solcher Eigenverantwortung besteht. Hier braucht es die Unterstützung von erfahrenen Entwickler*innen.

Codequalität & 4-Augen-Prinzip

Um eine hohe Softwarequalität zu erreichen, helfen z. B. Clean Code, Pair Programming und Code-Reviews. Alles Themen, die wir als technische Coaches vermitteln können. Allerdings muss die Umsetzung auch im Tagesgeschäft möglich sein. Ebenso wie für Tests und Architektur müssen die Teams auch hierfür den Kopf frei haben und Verantwortung übernehmen können. Einige Teams, denen wir begegnet sind, waren sich durchaus bewusst, wie man guten Code schreibt, klagten aber über Zeitdruck, Pairing-Verbot oder lange Wartezeiten für Reviews. In diesen Unternehmen wurden Methoden wie Pair Programming außerhalb der Entwicklung als Zeitverschwendung empfunden, ohne deren Vorteile für die Softwarequalität zu verstehen.

Dies sind wieder klare Anzeichen, dass die organisatorischen Rahmenbedingungen nicht stimmen. Wie wichtig Softwarequalität für die langfristige Entwicklungsgeschwindigkeit ist, muss unternehmensweit verstanden und in der Kultur verankert werden. Ansonsten verpuffen technische Schulungen wirkungslos, da nach dem ersten Enthusiasmus schnell auf alte Muster zurückgegriffen wird.

Agilität und Zusammenarbeit lernen

Um agile Softwareentwicklung effektiv zu betreiben, reichen technische Skills und Methoden nicht aus. Egal welches agile Vorgehen man nimmt, alle Beteiligten müssen lernen, mit den zugehörigen Werkzeugen und Praktiken effektiv umzugehen und ihre Rolle einzunehmen.

Bei Scrum, zum Beispiel, müssen nicht nur Scrum Master und Product Owner gecoacht werden, sondern auch Entwickler*innen müssen lernen, wie sie sich sinnvoll in Planning, Refinement und Retrospektive einbringen können. Alle Rollen müssen gut zusammenarbeiten und sich ergänzen. Die Teams sollten daher fachlich aufgeteilt und cross-funktional aufgestellt werden, sodass alle nötigen Expertisen vertreten sind, um Aufgaben Ende-zu-Ende abzuarbeiten. Nur so kann eine gemeinsame Verantwortung für Qualität entstehen. In rein technisch geschnittenen Teams kommt es hingegen oft zu Fehlern an den Schnittstellen und zu gegenseitigen Schuldzuweisungen, warum ein Feature in Integration am Ende doch nicht funktioniert.

Es kann dennoch teamübergreifende Software- und Architektur-Themen geben, die koordiniert werden müssen. Hier kann ein Entwicklungsteam nicht alleine agieren: Der Austausch zwischen Teams und mit teamübergreifenden Rollen muss von der Organisationsstruktur gefördert werden. Dafür muss die Organisation den Entwickler*innen die Freiheit und die Gelegenheit geben, um solche Themen voranzutreiben. Hier kann zum Beispiel die Etablierung von Communities of Practice helfen.

Entwicklungsleitung und Management-Buy-in

Wir erleben auch oft, dass die initiale Schieflage der Entwicklung, wenn wir gerufen werden, durch eine schwache oder nicht vorhandene Entwicklungsleitung zugelassen wurde. Kontinuierlicher Austausch, Verbesserung und der Rückfluss notwendiger Maßnahmen in Sprints und Roadmap können im Idealfall von Vertreter*innen der Teams selbst gemanagt werden. Hierfür müssen die Teams allerdings enabled sein. In den meisten Organisationen, die viele der oben beschriebenen Qualitätsprobleme haben, ist das Management aber nicht so aufgestellt, dass dies der Fall ist.

Deshalb haben wir gute Erfahrung damit gemacht, dass unsere Coaches sich kontinuierlich mit dem Management austauschen, um auch dort die Bereitschaft zu verankern, sich agil weiterzuentwickeln. Wird dies versäumt, behindert der Widerspruch zwischen klassischer Führung und agiler Entwicklung oft den Fortschritt und limitiert das Unternehmen stark. Dann bleibt es in Lagern: die da oben und die da unten – mit allen negativen Konsequenzen.

Für echte Veränderung braucht es auch ein Management-Buy-in und einen „Sponsor“ im Unternehmen, der die notwendigen Veränderungen und Maßnahmen (oft durch die Coaches initiiert) versteht und im Kreis des Managements vertritt. Er oder sie kann die nötigen Veränderungen in die Sprache des Managements übersetzen und helfen, die Organisation zu verändern und dabei alle Betroffenen mitzunehmen.

Schlussfolgerung

Hohe Qualität ist keine reine Technikfrage, sondern hängt von einem Zusammenspiel im gesamten Team ab:

  1. Produktvision und -ziele müssen klar herausgearbeitet werden.
  2. Die organisatorischen Rahmenbedingungen müssen stimmen.
  3. Das Team muss das nötige technische Know-how vorweisen.

Wir haben daher festgestellt, dass die beste Variante, unsere Kunden bei Qualitätsproblemen zu unterstützen, ein Team aus verschiedenen Coaches ist:

  1. Product Coaches unterstützen das Business bei der Ausrichtung des Produkts und der Prioritätensetzung.
  2. Agile Coaches unterstützen den Aufbau agiler Rahmenbedingungen und selbstorganisierter Teams.
  3. Technical Coaches helfen den Teams bei der praktischen Umsetzung agiler Softwareentwicklung.

In dieser Aufstellung können wir Unternehmen helfen, Qualitätsprobleme an der Wurzel anzupacken und die Qualität nachhaltig zu steigern.

Sie wollen wissen, wie auch Sie mehr Qualität in Ihrem Projekt erreichen können? Melden Sie sich gerne unverbindlich bei uns.

Avatar

Angelo Veltens arbeitet als Web-Developer bei codecentric Hamburg. Er begeistert sich sowohl für die Frontend-Entwicklung mit JavaScript, als auch die Backend-seitige Entwicklung mit Frameworks wie Grails oder Spring Boot.
Testautomatisierung auf allen Ebenen von Unit- bis Akzeptanztests, sowie der Aufbau von Continuous-Delivery-Pipelines zählen dabei ebenfalls zu seinen Stärken.

Avatar

Edward Byne ist als Consultant Software Engineer tätig. Er fühlt sich sowohl im Backend als auch im Frontend wohl. Er legt viel Wert auf sauberen, verständlichen und Test-getriebenen Code und auf die Implementierung praktischer und effizienter Lösungen für seine Kunden.

Über 1.000 Abonnenten sind up to date!

Die neuesten Tipps, Tricks, Tools und Technologien.
Jede Woche direkt in deine Inbox.

Kostenfrei anmelden und immer auf dem neuesten Stand bleiben!
(Keine Sorge, du kannst dich jederzeit abmelden.)

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.