Statische Codeanalyse – Betrachtung der technischen Schuld und Komplexität

In diesem Artikel wird dargestellt, welche Kennzahlen durch eine statische Analyse erhoben werden können und wie diese zu interpretieren sind. Hauptaugenmerk liegt dabei auf der technischen Schuld und der Komplexität.

Bei einem Code Review wird in der Regel mit einer statischen Analyse des Quellcodes unter Einbeziehung eines statischen Analyse-Tools begonnen. Dabei werden anhand von Software-Metriken verschiedene Kennzahlen analysiert. Am Beispiel von SonarQube zählen unter anderem folgende Kennzahlen dazu:

  • Coding Rules: Überprüfung, ob Verstöße gegen gängige Programmierregeln im Quellcode vorliegen (Bugs, Vulnerabilites & Code Smells).
  • Code Coverage: Testabdeckung des Quellcodes in Prozent.
  • Test Quality: Anzahl der durchgelaufenen, übersprungenen und fehlgeschlagenen Testfälle.
  • Technical Debt: Die technische Schuld beschreibt den geschätzten Aufwand zur Behebung der Code Smells in Personentagen.
  • Duplications: Anzahl der duplizierten Quellcodezeilen.
  • Comments: Anzahl der kommentierten und dokumentierten Zeilen an der Gesamtzeilenanzahl.
  • Complexity: Auswertung der Komplexität von Klassen und Methoden anhand gängiger Größen.

Über das Dashboard von SonarQube bekommt man schnell einen ersten Überblick über den aktuellen Stand des Projektes. Neben der Analyse des gesamten Quellcodes wird  auch immer eine Analyse vom neu hinzugefügten Code vorgenommen:

In diesem Artikel werden die technische Schuld und die Komplexität näher betrachtet.

Die technische Schuld bezeichnet die geschätzten Kosten zur Behebung der mit dem Analyse-Tool festgestellten Verstöße (Code Smells). Die Code Smells sind nach Ihrer Schwere sortiert eingeteilt in:

  • Blocker Issues
  • Critical Issues
  • Major Issues
  • Minor Issues
  • Info Issues

Verstöße der Schweregrade Blocker- und Critical sind in jedem Fall zu beheben, da diese zur Einschränkung des Anwendungsbetriebes führen können. Üblicherweise fließen in die technische Schuld beispielsweise Aufwände zur Auflösung von Codeduplikaten oder zur Vereinfachung komplexer Methoden ein. Aufwände zur Erhöhung der Kommentar- oder Dokumentationsquote oder zur Generierung einer höheren Testabdeckung sind kein Teil der technischen Schuld.

Neben der technischen Schuld gibt es auch noch das Verhältnis der technischen Schuld. In dieser wird das Verhältnis der technischen Schuld zum geschätzten Gesamtaufwand des Projektes betrachtet. In SonarQube wird dazu das ein Rating von A bis E, als ein so genanntes Maintainability-Rating, vergeben. Anhand dieses Ratings wird die Wartbarkeit der Applikation gemessen. Für eine abschließende Beurteilung ist aber immer das Zusammenspiel aller Kennzahlen zu betrachten und zu interpretieren. Eine weitere wichtige Kennzahl dazu ist beispielsweise die Komplexität.

Bei der Komplexität ist zwischen der zyklomatischen und der kognitiven Komplexität  zu unterscheiden. Die zyklomatische Komplexität wurde 1976 von Thomas J. McCabe entwickelt, stammt aus der Graphentheorie und beschreibt die Anzahl der Möglichkeiten eine Klasse oder Methode zu durchlaufen. Somit gibt die Kennzahl die maximale Anzahl an Testfällen an, die benötigt werden, um eine Zweigabdeckung von 100% zu erreichen. Die zyklomatische Komplexität sagt nichts über die Verständlichkeit einer Klasse aus. Eine Methode mit einer verschachtelten switch-Anweisung ist für den Entwickler beispielsweise häufig auf den ersten Blick zu verstehen, wird aber eine hohe zyklomatische Komplexität aufweisen.

Bei der zyklomatischen Komplexität würde diese Methode einen Wert von 8 erhalten. Als Grenzwert für eine maximale zyklomatische Komplexität wird im Regelfall in der Literatur und Praxis ein Wert von 10 angesehen. Ein reines Anwenden dieses Komplexitätsbegriffes ist daher umstritten. Aus diesem Grund wird noch die kognitive Komplexität erhoben. Die kognitive Komplexität ist ein Maß für die Verständlichkeit einer Klasse.

Auch hierbei wird ein Maximalwert von 10 angenommen. Die dargestellte Beispiel-Methode erhält einen Wert von 1, da sie im Kontrollfluss nicht unterbrochen wird, aber eine Verschachtelung enthält. Die Methode wird somit als sehr leicht verständlich angesehen.

Die kognitive Komplexität wird grundsätzlich anhand von drei Regeln ermittelt:

  • Strukturen, die es ermöglichen, dass mehrere Anweisungen leserlich in einem Block zusammengefasst werden können, werden ignoriert.
  • Für jede Unterbrechung im Fluss des Codes erhöht sich die kognitive Komplexität um 1.
  • Für jede Verschachtelung wird die kognitive Komplexität um 1 erhöht.

Für einen leicht wartbaren Code müssen sowohl die Grenzwerte der zyklomatischen, als auch der kognitiven Komplexität eingehalten werden. Dies sorgt für schmalen, aber verständlichen Code und erleichtert den Zugang von Entwicklern zu der Codebasis.

Die technische Schuld und die Komplexität sind sehr wichtige Kennzahlen für die erste Beurteilung eines vorliegenden Quellcodes. Anhand der technischen Schuld lässt sich schnell erkennen, ob verhältnismäßig viele Verstöße gegen gängige Programmierregeln gefunden werden konnten oder nicht. Häufig entsteht eine hohe technische Schuld durch unsaubere Arbeit. Dies kann im Projektalltag verschiedenste Ursachen wie Zeitdruck oder verschobene Prioritäten haben. Die Komplexitätskennzahlen bilden ein gutes Maß für die Verständlichkeit des Quellcodes und können somit auch als ein weiteres Indiz für die Machart einer Applikation hinzugezogen werden.

Diesen Beitrag teilen

Benny Schwarting
IT-Consultant
Als IT-Consultant kümmert sich Benny maßgeblich um die Projektkoordination und das Requirements Engineering. Dabei hat er stets für unsere Kunden und deren Anforderungen ein offenes Ohr und steht ihn mit guten Ideen zur optimalen Lösungsfindung zur Seite.