Dieser Artikel beschreibt, wie technische Schulden als Qualitätsindikatoren verwendet werden können, was technische Schulden sind, wie sie entstehen und wie sie zu handhaben sind, um die Softwarequalität in Projekten kontinuierlich zu verbessern.
Technische Schulden sind ein Problem
Technische Schulden (technical debt, TD) bei Software sind ein wachsendes Problem. Neu ist das Problem nicht, der Begriff existiert seit Anfang der 90er-Jahre, er wurde geprägt, um zu verdeutlichen, dass mangelnde Qualität in Software nicht einfach ignoriert werden darf, sondern Konsequenzen hat.
Da Schulden verzinst werden, wachsen sie typischerweise an, wenn sie nicht zurückgezahlt werden. Das Gleiche gilt für technische Schulden, wenn sie nicht berücksichtigt werden. Im Laufe der Jahre ist so ein großer Schuldenberg entstanden. Eine im November 2022 veröffentlichte Studie vom Consortium for Information & Software Quality [CISQ] beziffert die aktuellen technischen Schulden in Softwareprojekten allein für die Vereinigten Staaten von Amerika auf über 1,5 Billionen US-Dollar. Ihre Auswirkungen stellen das größte Hindernis für Änderungen an bestehenden Code-Basen dar.
Technische Schulden erhöhen den Aufwand für das Warten und Weiterentwickeln von Softwareprojekten signifikant. Infolgedessen dauert zum Beispiel das Beheben eines Problems bei hohen technischen Schulden bis zu 124 Prozent länger als bei niedrigen. Darüber hinaus schränken technische Schulden die Innovationsfähigkeit von Unternehmen grundlegend ein [HNS]. Im Durchschnitt verbringen Entwickler zwischen 23 und 42 Prozent ihrer Zeit, je nach Studie [Tor22, Stripe, Bes19], mit technischen Schulden. Im Gegensatz dazu liefern Unternehmen, die sich aktiv mit diesem Thema auseinandersetzen, bis zu 50 Prozent schneller. Es ist also höchste Zeit, sich mit den eigenen technischen Schulden auseinanderzusetzen.
Was sind technische Schulden?
Technische Schulden entstehen, wenn auf das Durchführen von Maßnahmen zur Sicherung und Steigerung von technischer Qualität verzichtet wird. Dazu gehören unter anderem das Aufschieben von Dokumentationen, der Verzicht auf vollständige Modul- oder Regressionstests, das Missachten von Compiler-Warnungen, die unzureichende oder fehlende Einhaltung von Codierrichtlinien, zu hohe Komplexität des Codes und Codewiederholungen.
Es gibt viele Gründe, warum oder wofür Schulden aufgenommen werden: externer oder interner Druck, eine neue Funktionalität schnell verfügbar zu machen, Schwächen in der Qualitätssicherung, entweder im Prozess selbst oder in der Implementierung, mangelhafte Kommunikation oder unzureichendes Wissen. Und das sind nur einige Beispiele.
Die obige Aufzählung zeigt, dass es relativ einfach ist, technische Schulden einzugehen. Wird dem nicht aktiv entgegengewirkt, können die technischen Schulden mit jeder Änderung und Erweiterung der Software – auch unwillkürlich – wachsen. Dies führt zum nächsten Problem der technischen Schulden: Sie sind in ihrer Gesamtheit schwer zu erfassen.
Beispiel: In einem fiktiven Unternehmen wird ein Produkt mit jeder neuen Version um zusätzliche Funktionalitäten erweitert. Im Laufe der Zeit dauert die Entwicklung immer länger und es werden immer mehr Fehler von den Kunden gemeldet. Die Entwicklungsabteilung erklärt, dass das Produkt zunehmend unwartbarer und schwieriger zu erweitern wird. Aber woran liegt das und was kann man dagegen tun?
Wie können technische Schulden gemessen werden?
Der erste Schritt im Umgang mit technischen Schulden besteht darin, sie zu messen. In Anbetracht der Bandbreite möglicher Quellen ist eine umfassende Messung jedoch schwierig. Einfacher ist es, sich auf bestimmte Aspekte der Software zu beschränken. Und da der Kern jeder Software mehr oder weniger aus Code besteht, ist dies eine gute Grundlage, um mit der Messung der bestehenden Schulden zu beginnen. Der Vorteil der Fokussierung auf Code ist, dass im Sinne des "Shift left"-Ansatzes schon sehr früh mit dem Messen der technischen Schulden begonnen werden kann. Dazu muss der Code weder kompiliert noch ausgeführt werden.
Die Palette an Werkzeugen, die bei der Entwicklung eingesetzt werden können, ist groß. Viele Daten zur Messung der bestehenden Schulden werden über statische Analysen gewonnen, die in jeder modernen Softwareentwicklung Anwendung finden sollten. Am weitesten verbreitet ist die Kontrolle der Einhaltung von Codierrichtlinien nach gängigen Standards wie zum Beispiel MISRA C:2012. Durch das Einhalten dieser Regeln soll die Qualität der Software, insbesondere bezüglich Zuverlässigkeit und Wartbarkeit, erhöht werden.
Weniger weit verbreitet ist die Messung von Code-Metriken wie der zyklomatischen Komplexität (auch McCabe-Metrik genannt), des Sprachumfangs oder einfacheren Dingen wie Anzahl der Parameter und Anweisungen einer Funktion und die Kommentardichte. Eine Sammlung dieser Metriken sind die sogenannten HIS-Sourcecode-Metriken, veröffentlicht im Jahr 2005 durch die Herstellerinitiative Software, einer Initiative namhafter Automobilhersteller, kurz HIS. Der Vorteil bei der Anwendung dieser HIS-Metriken ist, dass nicht nur die Metriken, sondern auch ein Zielbereich angegeben wird, um die Komplexität der Software beherrschbar zu halten.
Beispiel: Zur Analyse der Wartbarkeit des Codes werden im fiktiven Unternehmen Metriken erfasst. Es werden Grenzwerte für die zyklomatische Komplexität (<= 15), Kommentardichte (>= 20 %) und die Anzahl der Codezeilen (<= 35) von Funktionen festgelegt. Im nächsten Entwicklungssprint von drei Wochen werden die Funktionen überarbeitet, die am weitesten von den Grenzwerten abweichen.
Ein weiterer Aspekt, der ebenfalls statisch geprüft werden kann, ist das Vorhandensein von geklontem Code. Dies können Codeabschnitte oder vollständige Algorithmen sein. Solche Klone können problematisch werden, wenn der betreffende Code, der an anderer Stelle geklont wurde, verändert wird, beispielsweise durch Weiterentwicklung oder Fehlerkorrektur. Die gleichen Änderungen sollten dann an der geklonten Stelle ebenfalls durchgeführt werden, um die Konsistenz des Codes zu erhalten. Geschieht dies nicht, driften die Abschnitte langsam, aber sicher inhaltlich auseinander, was die Wartbarkeit erschweren und zu Verwirrung führen kann. Dies kann auch dazu führen, dass Fehler, die an einer Stelle des Codes gefunden und behoben wurden, an anderer Stelle noch vorhanden sind.
Um das Thema Qualität bei der Messung von technischen Schulden näher zu beleuchten, empfiehlt sich ein Blick in die Norm ISO/IEC 25010:2011. Diese gliedert die (Produkt-) Qualität von Software in acht verschiedene Charakteristika. Die Charakteristika Zuverlässigkeit und Wartbarkeit wurden bereits erwähnt. Alle Charakteristika sind wiederum in Unteraspekte gegliedert. Der Übersichtlichkeit halber ist dies bei der Wartbarkeit mit den Unteraspekten Testbarkeit, Veränderbarkeit und Wiederverwendbarkeit angedeutet (siehe Abbildung 1).
Abb. 1: Qualitätscharakteristika nach ISO/IEC 25010:2011 auf einen Blick
Wie werden technische Schulden berechnet?
Die Aufteilung der Qualität in verschiedene Aspekte hilft dabei, die technischen Schulden besser zu erfassen. An der „Gesamtsumme“ der Schulden ändert das zwar nichts, es ermöglicht jedoch, den Umfang und damit auch den Abbau der Schulden zu strukturieren, insbesondere wo am besten mit dem Schuldenabbau begonnen und in welcher Reihenfolge weitergemacht werden sollte.
Eine Methode, die auf den oben genannten Aspekten der Softwarequalität aufbaut, ist [SQALE]. Diese Methode priorisiert die Aspekte unter anderem nach ihrem Einfluss auf die typischen Aktivitäten im Lebenszyklus einer Softwareanwendung. Dabei bauen die Aspekte aufeinander auf. Beispielsweise ist die Herstellung von Veränderbarkeit nur dann möglich, wenn zuvor Testbarkeit und Zuverlässigkeit hergestellt wurden (siehe Abbildung 2).
Abb. 2: Das SQALE-Qualitätsmodell
Dabei kommen auch die Unteraspekte von Wartbarkeit zum Tragen, da nicht alle Unterpunkte der Wartbarkeit gleichzeitig adressiert werden müssen.
Um einen guten Überblick über die Art der Schulden und einen ersten Eindruck über deren Umfang zu erhalten, werden die gemessenen Daten, zum Beispiel aus den oben genannten statischen Analysen, mit den Qualitätsaspekten verknüpft. Was nun noch fehlt, ist ein Maß für die Höhe der Schulden. In der SQALE-Methode wird dieses Maß als "Korrekturkosten" bezeichnet. Ursprünglich wurde die Höhe als Geldbetrag angegeben.
In Projekten ist die vorherrschende Währung jedoch die Zeit. Da Zeit gleich Geld ist, kann das eine in das andere umgerechnet werden. Zudem ist einem Entwickler meist nicht bewusst, wie viel Geld eine Minute seiner Arbeit kostet. Andererseits kann ein erfahrener Entwickler ziemlich genau abschätzen, wie viel Zeit er benötigt, um ein Problem zu beheben. Zum Beispiel kann bei der Verletzung einer Regel der Codierrichtlinien ausreichend genau eingeschätzt werden, ob es sich um ein größeres Problem handelt, oder ob es mit sehr wenig Aufwand behoben werden kann (siehe Tabelle 1).
Tabelle 1: Beispiele der Zuordnung von Regelverletzungen zu Qualitätsaspekten und Korrekturkosten
Wie können technische Schulden beherrscht werden?
Werkzeuge, die die Zuordnung von Daten zu Qualitätsaspekten und die Verknüpfung mit Erfahrungswerten zu Korrekturzeiten (Korrekturkosten), zum Beispiel nach der SQALE-Methode, durchführen können, sind Datenanalysewerkzeuge, auch Data Intelligence Tools genannt. Der zusätzliche Nutzen dieser Tools besteht darin, dass sie alle Datenquellen für eine konsolidierte Analyse zusammenfassen können. Am Ende ergibt sich zumindest für die Bereiche, für die Daten vorliegen, sowohl ein Gesamtbild der aktuellen technischen Schulden als auch ein Plan, was in welcher Reihenfolge zu tun ist, um die technischen Schulden zu reduzieren (siehe Abbildung 3).
Abb. 3: Prozess und Datenfluss zur Messung technischer Schulden
Diese Bewertung sollte nicht nur gelegentlich durchgeführt werden. Alle Tools können in eine Continuous Integration Pipeline (CI) eingebunden werden. Man kann also bei jeder Änderung prüfen, ob man neue Schulden aufgenommen hat oder dabei ist, sie abzubauen. Es gibt auch Datenanalysewerkzeuge, die solche Trends überwachen und zum Beispiel eine Build-Chain anhalten, wenn ein Wert aus dem Ruder läuft. Somit kann verhindert werden, dass unbewusst weitere Schulden angehäuft werden.
Beispiel: Da die Qualitätsinitiative des fiktiven Unternehmens auf einen Sprint beschränkt war, ist nur ein Teil der Software innerhalb der Qualitätstoleranzen. Ein weiteres Reduzieren der technischen Schuld wird dadurch erreicht, dass jede Codeänderung in einer CI Pipeline auf die vorgegebenen Qualitätsgrenzwerte überprüft wird.
Beim Erstellen neuer Funktionen gelten strikte Grenzwerte für Komplexität, Kommentardichte und Codegröße. Bei Änderungen an bestehenden Funktionen, die die vorgegebenen Grenzwerte bereits überschritten haben, wird eine Überarbeitung dringend empfohlen. Da eine Änderung des Codes auch ein gewisses Verständnis für den Codezusammenhang voraussetzt, sollte eine Anpassung in der Regel mit vertretbarem Aufwand möglich sein.
Fazit und Ausblick
Qualität ist wichtig. In den meisten Fällen wird jedoch aus Unkenntnis oder absichtlich auf umfassende Qualität verzichtet. Die daraus resultierenden technischen Schulden sind ein wachsendes Problem, das angegangen werden muss. Nach dem Motto "Alles ist besser, als nichts zu tun" wird in diesem Artikel ein Ansatz beschrieben, der es ermöglicht, technische Schulden ohne einen einzigen Testfall und nur auf Basis statischer Analyseergebnisse zu bestimmen. Dabei helfen moderne Datenanalysewerkzeuge nicht nur beim Konsolidieren aller Daten, sondern auch bei der Bewertung der Ergebnisse. Nun gilt es, mit dem Abbau der Schulden zu beginnen.
Weitere Informationen
[Bes19] T. Besker, A. Martini, J. Bosch, Software developer productivity loss due to technical debt – A replication and extension study examining developers’ development work, ScienceDirect, siehe:
www.sciencedirect.com/science/article/abs/pii/S0164121219301335
[CISQ] The Cost of Poor Software Quality in the US: A 2022 Report, siehe:
www.it-cisq.org/the-cost-of-poor-quality-software-in-the-us-a-2022-report/
[HNS] The challenges of technical debt and how it impacts organizations, Help Net Security, siehe:
www.helpnetsecurity.com/2021/06/18/technical-debt-challenges/
[Stripe] The Developer Coefficient, Sept 2018, siehe:
stripe.com/files/reports/the-developer-coefficient.pdf
[SQALE] SQALE = Software Quality Assessment based on Lifecycle Expectations, according to „The SQALE Method for Managing Technical Debt” – Jean-Louis Letouzey, 2016, siehe:
www.cutter.com/article/managing-technical-debt-sqale-method-490726
[Tor22] A. Tornhill, M. Borg, Code Red: The Business Impact of Code Quality – A Quantitative Study of 39 Proprietary Production Codebases, arXiv:2203.04374 [cs.SE]