Suche

Kontinuierliche Inspektion: Wie Sie interne Softwarequalität objektiv messen und steuern

Milad Jason Daivandy
software-quality

© Shutterstock / Olivier Le Moal

Softwarequalität – Auftraggeber erwarten sie, Softwarehersteller werben damit und Anwender beklagen mitunter ihren Mangel. Nachvollziehbar also, dass jeder Stakeholder etwas anderes darunter versteht. Was interne Softwarequalität ist, was sie von anderen Aspekten der Softwarequalität unterscheidet und wie die Steuerung und Messung interner Softwarequalität zur Produktivität in der Softwareentwicklung beitragen kann, soll dieser Artikel zeigen.

Produktivität ist das Verhältnis von Ausbringungsmenge zu Einsatzmenge oder von Input zu Output. Angewendet auf die Softwareentwicklung ist der Output das Softwareprodukt und der Input der Aufwand. Dabei stellen sich jedoch einige Fragen: Welches sind die maßgeblichen Bestandteile des Outputs „Softwareprodukt“? Features, Dokumentation, Qualität, Modularität oder gar Lines of Code? Gibt es in der Softwareentwicklung weitere für den Output maßgebliche Metriken und falls ja, wie sind diese zueinander gewichtet? Der Produktivitätsbegriff erfordert Genauigkeit. Es muss also eine präzisere Definition gefunden werden. Das rechtfertigt einen genaueren Blick auf die Softwareentwicklung, die viele Disziplinen integriert, u. a. Projektmanagement, Anforderungsmanagement, Konzeption, Programmierung, Konfigurationsmanagement, Qualitätsmanagement, Releasemanagement. Jedes davon lässt sich in weitere Unterdisziplinen aufteilen. Ein Definitionsversuch für den Produktivitätsbegriff in der Softwareentwicklung sollte diesem Umstand Rechnung tragen und die Beziehungen der vorangestellten Disziplinen zueinander und den jeweiligen Beitrag zum Gesamtergebnis bewerten können. Plewan und Poensgen haben in [1] folgende Faktoren ermittelt, die maßgeblich die Produktivität in der Softwareentwicklung bestimmen:

  1. Ziele genauestens definieren
  2. Den Kern der richtigen Anforderungen treffen
  3. Hochleistungsteams aufbauen
  4. Vorgehen ohne effektive Methodik abstellen
  5. Qualität steigern und Rework radikal reduzieren
  6. Verschwendung erkennen und eliminieren
  7. Projekte richtig in die Umgebung integrieren
  8. Steuerung von Fortschritt, Qualität und Produktivität

Vor diesem Hintergrund liegt der Schwerpunkt dieses Beitrags auf der Bedeutung der internen Softwarequalität für die Produktivität sowie auf einer Einführungsstrategie für die Steuerung interner Softwarequalität für Projekte. Der Artikel richtet sich an den interessierten Leser, vor allem aber an Entwickler, Testmanager, Qualitätsmanager und Projektmanager. Es wird ein Ansatz vorgestellt, der einheitlich und nachvollziehbar zwischen den Welten des Testmanagements und der Entwicklung(-stests) vermitteln soll (Abb. 1). Der Einstieg erfolgt mit einer Begriffsklärung zu interner Softwarequalität, grenzt diese unter Bezugnahme auf bewährte Softwarequalitätsmodelle von anderen Aspekten der Softwarequalität ab und zeigt, dass Codequalitätsmanagement einen großen Teil von internem Softwarequalitätsmanagement ausmacht. Danach wird herausgearbeitet, welchen Einfluss Codequalitätsmanagement auf externe Softwarequalität ausübt. Anschließend wird eine Zuordnung von konkreten Codemetriken zu internen Softwarequalitätsattributen vorgenommen. Der daraus resultierende Mehrwert für verschiedene Stakeholder in der Softwareentwicklung wird anschaulich erklärt, u. a. welche Aussagekraft von bestimmten Codemetriken zu erwarten ist. Daraufhin wird kontinuierliche Inspektion als Implementierung von Codequalitätsmanagement sowie als Erweiterung von kontinuierlicher Integration vorgestellt. Auf dieser Basis wird schließlich eine Einführungsstrategie in Projekte mit dem Werkzeug SonarQube vorgestellt.

Abb. 1: Grauzone zwischen Entwicklung(-stests) und Testmanagement

Abb. 1: Grauzone zwischen Entwicklung(-stests) und Testmanagement

Interne Softwarequalität – was ist das?

Für den Begriff der Softwarequalität gibt es viele Definitionen, deren vollständige Gegenüberstellung den Umfang dieses Artikels sprengen würde. Zur Ermittlung des Konzepts von interner Softwarequalität beschränken wir uns folglich auf die Betrachtung von zwei Softwarequalitätsmodellen: das Modell nach Boehm [2] und ISO 9126.

Das Softwarequalitätsmodell nach Boehm (Abb. 2) organisiert Softwarequalität in die zwei Kategorien Effektivität und Erhaltbarkeit, die über zwei Hierarchieebenen zuerst in konkretere Anforderungen und daraus schließlich in Qualitätsattribute detailliert werden. Dabei sind diese Qualitätsattribute durch Metriken objektiv messbar. Auffällig ist dabei, dass Effektivität sich auf nicht funktionale Anforderungen hinsichtlich der Anwendung des Softwareprodukts bezieht (z. B. Benutzbarkeit, Zuverlässigkeit) und Erhaltbarkeit auf die Entwicklung des Softwareprodukts abzielt (z. B. Testbarkeit, Änderbarkeit). Auch wenn dies nicht explizit genannt ist, könnte man stattdessen von einer externen (anwendungsgerichteten) und internen (entwicklungsgerichteten) Softwarequalität sprechen.

Abb. 2: Softwarequalitätsmodell nach Boehm

Abb. 2: Softwarequalitätsmodell nach Boehm

Das Qualitätsmodell nach ISO 9126 organisiert Softwarequalität in vier Bereiche und erweitert das Modell von Boehm mit einem Qualitätsmodell, internen und externen Qualitätsattributen und der Nutzungsqualität. Die Erweiterungen sind als Teile 1 bis 4 unter [3] angegeben. Das Qualitätsmodell nimmt eine Klassifizierung von Softwarequalität gemäß so genannter Softwarequalitätsmerkmale (z. B. Wartbarkeit) vor, die jeweils in Qualitätsattribute (z. B. Änderbarkeit, Testbarkeit, Analysierbarkeit) verfeinert werden (Abb. 3). In diesem Kontext findet eine Unterscheidung in interne und externe Qualitätsattribute statt, die jeweils durch interne und externe Qualitätsmetriken quantifizierbar sind. Interne Qualitätsmetriken beziehen sich auf das Softwareprodukt und seine Zwischenprodukte während der Entwicklungsphase, z. B. Quellcode, Designdokumente und Anforderungsdokumente. Externe Qualitätsmetriken bezeichnen das Verhalten des Produkts im Testmanagement (z. B. Testabdeckung, Anzahl der Defects) und Produktivbetrieb. Schließlich zielt die Nutzungsqualität auf den expliziten Nutzen des Softwareprodukts für seinen Anwender in konkreten Anwendungskontexten ab und nennt auf erster Ebene die vier Qualitätsmerkmale Produktivität, Effektivität, Sicherheit und Zufriedenheit.

Abb. 3: Softwarequalitätsmodell nach ISO 9126

Abb. 3: Softwarequalitätsmodell nach ISO 9126

In Abbildung 4 wird der Zusammenhang zwischen den einzelnen Qualitätsdimensionen verdeutlicht: Prozessqualität wirkt auf interne Qualitätsattribute, die wiederum externe Qualitätsattribute beeinflussen. Diese haben einen direkten Effekt auf die Nutzungsqualität des Softwareprodukts. Hervorzuheben ist hierbei, dass jede dieser vier Qualitätsdimensionen durch einen eigenen Prozess gesteuert wird, der Metriken produziert:

  • Prozess bezieht sich auf den Softwareentwicklungszyklus (vgl. [3], Part 1, S. 3)
  • Zu internen Qualitätsmetriken zählen mittels statischer Codeanalyse ermittelte Codemetriken
  • Externe Qualitätsmetriken (z. B. Testabdeckung, Fehlerrate) ergeben sich durch Testmanagement
  • Nutzungsqualität (siehe oben) durch Usability Engineering
Abb. 4: Abhängigkeiten der vier Qualitätsdimensionen nach ISO 9126

Abb. 4: Abhängigkeiten der vier Qualitätsdimensionen nach ISO 9126

Interne Softwarequalität bezieht sich auf strukturelle Eigenschaften von Software. Dazu gehören der Quellcode, seine Organisation (Softwarearchitektur und Softwaredesign) und Dokumentation (z. B. Anforderungen, Konzeption, API-Dokumentation), Elemente mit einem starken Bezug zu technischer Schuld. Man könnte auch sagen: Je höher die interne Softwarequalität, desto besser die Softwarearchitektur und desto geringer die technische Schuld. Auch korrekt ist die Aussage: Je höher die interne Softwarequalität, desto geringer die Aufwände für Veränderungen bzw. Change Requests. Hierbei soll nicht verschwiegen werden, dass interne Softwarequalität und ihre Steuerung ebenfalls Aufwände erfordern, allerdings mit zunehmendem Abbau bzw. Vermeidung neuer technischer Schulden eine mittel- bis langfristige Amortisation dieser Aufwände das Ziel sein sollte.

Interne Softwarequalität und ihre Bedeutung für die Softwareentwicklung

Die zuvor aufgestellten Beziehungen zwischen interner Softwarequalität, Softwarearchitektur und technischer Schuld klingen aus der Vogelperspektive schlüssig, sollen aber im Folgenden konkreter untersucht werden. Mit Ausnahme von Prototyping spielt interne Softwarequalität für die meisten Softwareprojekttypen eine große Rolle, sei es für Sanierungsprojekte, Evolutionsprojekte, Integrationsprojekte oder auf der Grünen Wiese. Angelehnt an die Softwarequalitätsmodelle nach Boehm und ISO 9126 betrachten wir folgende Qualitätsattribute jeweils mit einigen wichtigen Auswirkungen auf Softwareprojekte:

  • Testbarkeit: Automatisierte Entwicklertests (Unit Tests und Integrationstests), Veränderbarkeit
  • Veränderbarkeit: Bugfixing, Change Requests, neue Features
  • Modularität: Austauschbarkeit, Testbarkeit, Architektur
  • Kompaktheit: Lesbarkeit, Veränderbarkeit, Modularität
  • Lesbarkeit: Analysierbarkeit, Einarbeitung neuer Entwickler, Fehlersuche

Eine konsequente und standardisierte Anwendung dieser Qualitätsattribute durch alle Stakeholder eines Softwareprojekts hat das Potenzial, eine einheitliche und effektive Kommunikationsgrundlage für wichtige Entscheidungen im Spannungsfeld Technologie und Business zu schaffen (z. B. hinsichtlich der Steuerung technischer Schuld im Konflikt mit geplanten Featureerweiterungen). Zudem kann so der Zustand der projektierten Software noch objektiver erfasst und gegebenenfalls zuvor unsichtbare Risiken kenntlich gemacht werden. Qualitätskriterien für Deliverables können festgelegt werden (z. B. für die Steuerung externer Dienstleister) und Vergleiche zwischen Softwareprojekten werden ermöglicht (entsprechende Erfahrung mit kontinuierlicher Inspektion, Codemetriken und entsprechenden Softwareprojekttypen vorausgesetzt). Durch die standardisierte Anwendung der Qualitätsattribute könnte auch offengelegt werden, an welchen Stellen ein Softwareprojekt den dringendsten Ausbesserungsbedarf hat (z. B. bei Analyse- bzw. Sanierungsprojekten).

Dieses Potenzial steht und fällt mit der korrekten Anwendung geeigneter interner Qualitätsmetriken, im folgenden Codemetriken genannt. Natürlich kann die Auswahl interner Softwarequalitätsmetriken zwecks Softwarequalitätsmanagement nur effektiv sein, sofern sie projektspezifisch erfolgt. Allerdings sind die im folgenden ausgewählten Codemetriken für die meisten Softwareprojekte – abgesehen vom Prototyping – unverzichtbar, wenn man mit zunehmender Softwarekomplexität eine wirtschaftliche und effektive Qualitätssicherung (Testbarkeit, Testautomatisierung) sowie Erweiterbarkeit (Change Requests) und Veränderbarkeit (z. B. Bugfixes) aufrechterhalten möchte. Hierzu nimmt Tabelle 1 jeweils eine Zuordnung zwischen Qualitätsattributen, ihren Erfüllungsvoraussetzungen und dazu geeigneten Codemetriken vor. Hierbei erfolgt nur ein kurzer Abriss, es wird kein Anspruch auf Vollständigkeit erhoben.

Tabelle 1: Zuordnung von Codemetriken zu internen Softwarequalitätsattributen

Tabelle 1: Zuordnung von Codemetriken zu internen Softwarequalitätsattributen

Isoliert betrachtet liefert jede Codemetrik ein Indiz [4] dafür, dass bestimmte Teile des Quellcodes eine gute oder schlechte Qualität haben. In erster Linie ist es aber nur ein Verdachtsmoment, der sich erst noch erhärten muss. Daher ist es wichtig, ein und denselben Teil des Quellcodes anhand verschiedener Codemetriken im Verbund zu bewerten und entsprechende Codesegmente genauer zu untersuchen, z. B. in einem (Mini-)Code-Review. Bewährt hat sich in diesem Zusammenhang die zusätzliche Anwendung von SOLID, eines Akronyms, das fünf für die objektorientierte Programmierung (OOP) und das objektorientierte Design (OOD) wichtige Prinzipien zusammenfasst.

Anhand des ersten dieser Prinzipien, dem so genannten Single Responsibility Principle (Kasten: „Single Responsibility Principle“), soll die Vorgehensweise erläutert werden, wie ausgehend von ausgewählten Codemetriken unterschiedliche Stakeholder Aussagen über die interne Softwarequalität treffen können.

Single Responsibility Principle

Das Single Responsibility Principle (SRP) fordert von einer Klasse, dass sie nur eine Verantwortlichkeit hat. Alternativ spricht man auch davon, dass eine Klasse nur einen Grund haben sollte, geändert zu werden. In diesem Zusammenhang spricht man auch von Kohäsion: Eine Klasse mit mehreren Verantwortlichkeiten hat eine geringere Kohäsion, als eine Klasse, die sich nur einer klar umrissenen Verantwortlichkeit angemessen annimmt. Angemessen bedeutet, dass eine zu große Verantwortlichkeit (die Größe ist objektivierbar durch bestimmte Codemetriken, siehe Tabelle 1) in kleinere Verantwortlichkeiten zerlegt und ggfs. über mehrere miteinander kollaborierende Klassen verteilt werden sollte. Unangemessen wäre es in einem solchen Fall, stattdessen eine Klasse zu erzeugen, die ihrer Größe wegen nur schwer wartbar ist. Neben Klassen findet das SRP auch Anwendung auf Methoden und Packages. Hintergrund dieses Prinzips ist, dass man eine Verantwortlichkeit isoliert von anderen Verantwortlichkeiten ändern können möchte. So lassen sich teure Kaskadeneffekte (reduzierte Lesbarkeit; aufwändigere Veränderbarkeit; erhöhter Synchronisationsaufwand, falls mehrere Entwickler parallel an einer übergroßen Verantwortlichkeit arbeiten) vermeiden.

Spielen wir vier Beispiele aus einem Java-Softwareprojekt durch:

Beispiel 1: Dass Verantwortlichkeiten für zwei klar voneinander getrennte Features wie Drucken und Authentisierung nicht in dieselbe Klasse (und auch nicht in dasselbe Package) gehören, ist nachvollziehbar. Das sind eindeutig zwei sehr unterschiedliche Verantwortlichkeiten.

Beispiel 2: Bedeutet das im Umkehrschluss, dass der gesamte Quellcode für Authentisierung in eine Klasse gepackt werden sollte? Eine Antwort darauf hängt neben dem Anforderungsumfang von Wissen und Erfahrung des jeweiligen Entwicklers ab. Ein erfahrener Entwickler könnte hierbei zuverlässige Erfahrungswerte darüber entscheiden lassen. Beispielsweise könnte er anhand der Anzahl benötigter Authentisierungsfeatures, des verwendeten Frameworks und einschlägiger Erfahrung die Methodenanzahl und die jeweiligen Lines of Code (LOC) grob abschätzen. Bei einer sehr simplen Authentisierung ohne Passwortverschlüsselung ist somit durchaus denkbar, dass eine Klasse mit weniger als drei bis fünf relativ simplen Methoden genügen kann. Weitere Verantwortlichkeiten (Persistenz, Autorisierung) würden an entsprechende Klassen delegiert.

Beispiel 3: Nun soll die Authentisierung ergänzt werden um eine Passwortverschlüsselung, eine Unterscheidung in Groß-/Kleinschreibung, ein Rate Limiting und um die Validierung auf unzulässige Zeichen zwecks vorzeitigen Authentisierungsabbruchs. Hierbei könnte ein unerfahrener Entwickler einige folgenschwere Fehler begehen. Er könnte jedes Feature in derselben Authentisierungsklasse unterbringen, schließlich geht es doch im Groben nach wie vor um dieselbe Verantwortlichkeit: Authentisierung. So könnte sich die anfänglich schlanke Authentisierungsklasse mit einigen wenigen übersichtlichen Methoden und starker Kohäsion im Laufe der Zeit wesentlich vergrößern (LOC und Methodenzahl der Klasse). Dabei würden innerhalb der Methoden die Verarbeitungsschritte (LOC pro Methode) und deren Verschachtelungen mit Conditionals und Schleifen (zyklomatische Komplexität) ebenfalls zunehmen. Dies hätte Auswirkungen auf Testbarkeit, Lesbarkeit, Veränderbarkeit und Austauschbarkeit (z. B. des Verschlüsselungsalgorithmus für das Passwort). Letztlich hätte die derartig erweiterte Authentisierungsklasse gleich drei weitere Gründe, geändert zu werden.

Da die Auswirkung dieser ungünstigen Designentscheidungen mittels Codequalitätsmanagement messbar ist (Zeilen- und Methodenzahl der Klasse, Zeilenzahl der Methoden, zyklomatische Komplexität), würde dies – entsprechende Prozesse und automatisiertes Tooling für Codequalitätsmanagement vorausgesetzt – sehr schnell auffallen, idealerweise dem Verantwortlichen, vielleicht aber auch einem anderen Entwickler oder dem Projektleiter. Der Verantwortliche wüsste anhand der Codemetriken, dass er an dieser Stelle nicht qualitätskonform gearbeitet hat. Nach Abgleich der Codemetriken mit seinem Code erkennt er, dass er eine ungünstige Designentscheidung getroffen hat, die er eigenständig oder ggfs. mit Unterstützung durch einen erfahreneren Entwickler verbessern kann.

Beispiel 4: Der Projektleiter wüsste bei entsprechender Häufung bestimmter Codemetriken, dass an einigen Stellen die interne Softwarequalität riskiert wird und könnte rechtzeitig gegensteuern. Betrachten wir die Codemetrik der zyklomatischen Komplexität genauer: Angewendet auf ein Codesegment, z. B. eine Methode, misst sie die Menge der linear unabhängigen Pfade auf dem Kontrollflussgrafen dieses Codesegments. Mit zunehmender Menge dieser Pfade steigen die Testaufwände. Zum einen, da mit jedem zusätzlichen Pfad zusätzliche Tests geschrieben werden müssen. Zum anderen, da komplexer Code zu vergleichbar komplexen Tests führt. Weiterhin verschlechtert sich die Lesbarkeit. Je höher also die zyklomatische Komplexität einer Methode, desto komplexer und unlesbarer ist diese Methode. Außerdem kann eine besonders hohe zyklomatische Komplexität einer Methode ein Indiz dafür sein, dass diese Methode eine geringe Kohäsion hat, also mehrere Verantwortlichkeiten bedient; oder aber eine für eine einzige Methode zu große Verantwortlichkeit, die in mehrere Unterverantwortlichkeiten angemessener Größe zerlegt und über mehrere Methoden verteilt werden sollte.

Codequalitätsmanagement mit kontinuierlicher Inspektion

Der Kerngedanke von kontinuierlicher Integration ist bekannt: Bauen und Testen von Software nach jeder Änderung am Code erhöht die Sichtbarkeit von Defekten und reduziert drastisch deren Lebensdauer – sofern eine Fehlerbehebung stattfindet. Der Einsatz eines konfigurierbaren Build Breakers (z. B. nach fehlgeschlagenen Unit Tests) motiviert ggfs. dazu.

Kontinuierliche Inspektion denkt diese Idee konsequent für Codequalitätsmanagement weiter und klinkt sich in die Infrastruktur von kontinuierlicher Integration ein (Abb. 5), um den Quellcode eines Softwareprojekts mittels statischer Codeanalyse in Form von Codemetriken hinsichtlich Abhängigkeiten, Komplexität, Codeduplikaten, Testabdeckung und Coding-Standards zu messen. Mit Codequalitätsmanagement und Sichtbarmachung von Codequalität als Oberziele dienen diese Ergebnisse drei Prozessen (vgl. [5], S. 161 ff.):

  • das Unternehmen oder Projekt definiert Standards und Ziele für das Codequalitätsmanagement
  • die Entwicklung behebt gezielt und priorisiert Qualitätsmängel im Code
  • Code- und Designreviews werden strukturiert und gezielt durchgeführt.
Abb. 5: Kontinuierliche Inspektion – ein typischer Workflow

Abb. 5: Kontinuierliche Inspektion – ein typischer Workflow

Kontinuierliche Inspektion, ein Teil von „Prozess“ nach ISO 9126 (Abb. 4), ist kein definierter Standard. Um die Möglichkeiten für internes Softwarequalitätsmanagement zu verdeutlichen, betrachten wir an dieser Stelle das Open-Source-Werkzeug SonarQube, das sich in den vergangenen fünf Jahren im Rahmen von kontinuierlicher Inspektion aufgrund seiner Zugänglichkeit, Mächtigkeit und Multi-Plattform-Unterstützung bewährt hat. SonarQube stellt weitere Konzepte zur Verfügung, die das Codequalitätsmanagement stärken sollen: Quality Gates zeigen die Verletzung (sinnvoll) definierbarer Schwellwerte für Codemetriken bzw. Issues an – beispielsweise infolge einer zu hohen zyklomatischen Komplexität, zu niedrigen Unit-Test-Abdeckung oder zu vielen zyklischen Abhängigkeiten. Optional löst die Verletzung eines Quality Gate einen Build Breaker aus, der den CI-Build fehlschlagen lässt. Weiterhin lassen sich mehrere Quality Gates logisch miteinander verknüpfen.

Zusätzlich zum in Abbildung 5 gezeigten Workflow kann ein Entwickler vor einem (größeren) Commit eine lokale statische Codeanalyse durchführen. SonarQube ermöglicht hierzu eine so genannte Previewanalyse aus der Entwicklungsumgebung heraus, ohne dass der Entwickler lokal Werkzeuge für statische Codeanalyse installieren muss. SonarQube liefert als Output neben den eigentlichen Codemetriken zusätzlich so genannte Issues. Das sind objektiv ermittelte Regelverletzungen, die sich auf Codemetriken, Coding-Standards und potenzielle Designfehler (z. B. Exception Handling, Komplexität) beziehen und die in aufsteigende Schweregrade (Info, Minor, Major, Critical, Blocker) eingestuft werden. SonarQube hinterlegt zusätzlich die Historie der kontinuierlich ermittelten Codemetriken (bzw. Codequalität) sowie Issues und ermöglicht damit ein Trending des Softwareprojekts. Auf diese Weise können kritische Fragen bzgl. der Entwicklung der internen Softwarequalität und somit der technischen Schuld eindeutig beantwortet werden, z. B.: Wie gut war das Unit Testing (Testabdeckung und Testerfolgsrate) für alle Commits seit vorgestern? Wieviel duplizierter Code wurde während der letzten zwei Wochen hinzugefügt? Wurden in der aktuellen Iteration kritische Issues hinzugefügt?

Weiterhin ermöglicht die Historie den Vergleich zwischen Softwareprojekten hinsichtlich der Codequalität. Dabei sollte die jeweilige Projektart berücksichtigt werden: Bei Integrations- und Evolutionsprojekten erbt die Entwicklung mitunter architektonische Altlasten, die sich guter und effektiver Softwarearchitektur (und somit interner Softwarequalität) in den Weg stellen. Es ist durchaus vorstellbar, dass zur Sicherstellung ausreichend hoher interner Softwarequalität für Weiterentwicklungen zuerst einige zeitintensive Refactorings durchgeführt werden müssen. Der direkte Vergleich mit einem Grüne-Wiese-Projekt könnte daher hinken, da dieses mit einer technischen Schuld von Null startet.

Ausgehend von SonarQube, das in eine Infrastruktur für kontinuierliche Integration eingebunden ist, betrachten wir nun eine mögliche Einführungsstrategie in Softwareprojekte mit vorhandener technischer Schuld (Integrations-, Evolutions- und Sanierungsprojekte), jedoch keine Grüne-Wiese-Projekte.

Vorbereitend wird Stakeholder-spezifisch der Mehrwert von Codequalitätsmanagement vermittelt. Hierbei wird sich das Entwicklungsteam (inkl. Architekten, Testern und Projektleiter) stärker für technische Details (z. B. Codemetriken, siehe Tabelle 1) interessieren. Geschäftsführung und Kunden werden sich dafür interessieren, wie mit Investition in den Abbau technischer Schuld mittel- bis langfristig Erweiterungs- und Änderungskosten reduziert werden können.

Integrations-, Evolutions- und Sanierungsprojekte beginnen mit der Ermittlung der größten Schmerzpunkte hinsichtlich Codequalität, da deren Korrektur die größten positiven Auswirkungen hat. Dies geschieht mittels einer initialen SonarQube-Analyse des Quellcodes. Erfahrungsgemäß handelt es sich dabei um Codeduplikation, zyklische Abhängigkeiten, zyklomatische Komplexität, Erfolgsrate von Unit und Integrationstests sowie Testabdeckung. Bei Letzterer ist es sinnvoll, zuerst in eine ausreichende Unit-Test-Abdeckung zu investieren, bevor es ans Integration Testing geht. In einem anschließenden Code- bzw. Designreview wird die Softwarearchitektur auf Basis der Codemetriken und Issues grob hinsichtlich potenzieller Hindernisse für die Erweiterungen bewertet. Auf dieser Basis werden einige wenige Codemetriken, üblicherweise zwei bis drei, ausgewählt. Hierbei ist sicherzustellen, dass jeder Beteiligte Bedeutung und Aussagekraft dieser Codemetriken für die interne Softwarequalität versteht und akzeptiert. Anhand dieser Codemetriken wird ein Quality Gate definiert. Das Auslösen eines Build Breakers bei Verletzung des Quality Gate kann anfänglich optional sein, sollte aber mittel- bis langfristig standardmäßig Anwendung finden.

Die Initialphase, die einige wenige Iterationen dauern kann, hat folgenden Ablauf:

  • Das Projekt setzt sich das Ziel, dass diese Codemetriken sich nicht verändern. Mit zunehmendem Featureumfang entspricht dies bei den oben genannten Codemetriken einer absoluten Verbesserung der Codequalität.
  • Obwohl kontinuierliche Inspektion mittelfristig Code-Reviews nach Bedarfslage (indiziert durch Warnungen durch Codemetriken und Issues) ermöglicht, empfiehlt sich für die Initialphase das Durchführen regelmäßiger Code- bzw. Designreviews. Diese sollten durch Action Items aus SonarQube, also den ausgewählten Codemetriken bzw. Issues gesteuert werden. Die Action Items werden dabei von SonarQube anhand der ausgewählten Codemetriken bzw. Issues geliefert.
  • Nach dieser Initialphase findet eine Bewertung statt. Es soll geprüft werden, wie sich die verbesserte Codequalität auf die Produktivität ausgewirkt hat. Hierbei sollte nicht nur das Entwicklungsteam einbezogen werden, sondern auch Geschäftsführung und der Kunde. Dies muss nicht im selben Meeting geschehen: Während für das Entwicklungsteam auch Codemetriken und deren Bezug zum Quellcode bzw. Testing wichtig sind, haben Historie und Trending der Codemetriken einen höheren Kommunikationswert für Stakeholder ohne technologischen Hintergrund. Eingespielte Scrum-Teams können zusätzlich die Velocity als Referenz verwenden. Dabei sollte ein Bezug zu jeweiligen Entwicklungsaufgaben hergestellt werden: Die Entwicklung eines vergleichsweise isolierten Features hängt weniger von internen Softwarequalitätsattributen wie Veränderbarkeit bzw. Analysierbarkeit ab, als z. B. vom Austausch vorhandener Kernfeatures. Etwaige Reibungspunkte und Produktivitätsbremsen sollen ebenfalls geklärt werden und in die Planung für die nächste Iteration einfließen. Die Produkt- und Prozessinspektion (vgl. hier, S. 11–13) agiler Frameworks kann hierbei helfen.
  • Die zweite Phase unterscheidet sich von der ersten dadurch, dass die ausgewählten Codemetriken nun verbessert werden sollen. Mit zunehmender Projekterfahrung mit und im Vertrauen in kontinuierliche Inspektion können regelmäßige Code- bzw. Designreviews durch von SonarQube indizierte (Quality Gate, Codemetriken, Issues) ersetzt werden.
  • In der dritten Phase werden weitere Codemetriken bzw. Issues ausgewählt, einem zusätzlichen Quality Gate zugeordnet und entsprechend der ersten und zweiten Phase behandelt.

Unter Codemetriken nimmt Testabdeckung eine Sonderrolle ein: Eine Erhöhung der Unit-Test-Abdeckung von 40 Prozent auf 60 Prozent wirkt auf den ersten Blick hin positiv. Bewertbar wird diese statistische Verbesserung allerdings erst nach Betrachtung dessen, was die Unit Tests testen. Wichtig für den Produktivbetrieb sind vor allem Ausnahme- und Fehlerbehandlung und etwaige Recovery-Fähigkeiten. „Happy Path Testing“, also „Schönwettertesten“ sowie weitere Wege, wie Testabdeckung (un)wissentlich missbraucht werden kann, sollten durch eine klare Teststrategie vermieden werden. Die Überprüfung der Konformität einer solchen Teststrategie sollte Teil der Code-Reviews sein.

Abb. 6: SonarQube – Dashboard der öffentlichen Demo

Abb. 6: SonarQube – Dashboard der öffentlichen Demo

Nach diesem Durchstich von Produktivität durch Softwarequalitätsmodelle und Codemetriken hindurch bis zu kontinuierlicher Inspektion mag man denken: „Das hört sich alles toll an, ist aber sicherlich sehr aufwändig und lernintensiv. Außerdem muss ich SonarQube erst einmal in der Firma installiert kriegen …“. Praktisch ist, dass es mit http://nemo.sonarqube.org eine öffentliche Demo zu SonarQube gibt, die eine Vielzahl bekannter Open-Source-Projekte seit mehreren Jahren kontinuierlich inspiziert. Wer also schon immer wissen wollte, wie es um die interne Softwarequalität des Apache Tomcat bestellt ist, kann sich einen genaueren Überblick über den Trend der internen Softwarequalität verschaffen. Wie ein Detektiv untersucht man dabei ausgehend von Codemetriken auf dem Dashboard (Abb. 6) mittels Drilling-Down bis auf Quellcodeebene hinunter, ob sich der ein oder andere Verdacht auf Codesünden erhärtet. Try it!

Aufmacherbild: Compass needle pointing the blue text via Shutterstock / Urheberrecht: Olivier Le Moal

Geschrieben von
Milad Jason Daivandy

Milad Jason Daivandy entwickelt seit sechszehn Jahren Software, am liebsten verteilte Systeme (Grid Computing, SOA mit SOAP und REST, Webanwendungen) in Interoperabilitätsszenarien. Ob als Entwickler, Projektleiter oder Abteilungsleiter – in seinem Werkzeugkasten aus Java, PHP und Groovy ist immer Platz für Akronyme wie ATAM, FURPS oder arc42. Während Einsätzen als Softwarearchitekt und Berater in E-Science und Industrie hat er eine Leidenschaft für Messbarkeit von Softwarequalität entwickelt, die er (manchmal zu) begeistert mit seiner Umwelt teilt.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.