Code-Qualität. Metriken. Messung. Bewertung. Ich bin es leid. Ich bin es so sehr leid, dass ich es hier ein für alle mal niederschreibe.
Als mittlerweile langjähriger Berater für agile Software-Entwicklungs-Methodik reicht es mir langsam, immer wieder die gleichen grundlegenden Weichenstellungen zum Thema “Messung von Code Qualität” zu geben.

Alleine in den letzten 2 Jahren habe ich locker ein halbes dutzend Mal Kunden und Teams zu diesem Thema beraten.
Das frappierende dabei: fast jedes mal mussten die absoluten Grundlagen vermittelt und durchgearbeitet werden. Ich erwarte ja nicht, dass alles schon picobello umgesetzt ist.
Aber es ist heutzutage garnicht mehr so schwer, die fundamentalen Grundlagen in die richtige Richtung zu lenken. Denke ich zumindest. Es scheint wohl doch nicht immer zu gelingen, wie mehrfach meine Erfahrung mich belehrte.
Prolog
So. Um nun nicht immer wieder von Null anfangen zu müssen, veröffentliche ich hier ein original Statement-Papier zum Thema “Code Quality KPI’s”. Es wurde von mir für einen Kunden als erste Antwort auf seine bisherige “KPI-Strategie” verfasst. Der folgende Text ist O-Ton aus einer Antwort-Mail.
Nomenklatur
Die “Strategie-Aussagen” des Kunden habe ich als Zitate angeführt.
Beispiel:
Aussage: Code-Qualität ist wichtig für den Projekterfolg.
Die eben zitierte Aussage stellt ein “Strategie-Punkt” des Kunden dar, den ich hier – im Freitext – behandle bzw. erwidere.
Motivation
Das ganze mache ich in der – wohl eher idealistischeren – Hoffnung, dass sich einige Software-Projekt-Manager oder Entwicklungsleiter hierher verirren und sich mit den Grundlagen der Messung von Codequalität zumindest auseinandersetzen.
Denn wenn die Grundlagen schon mal sitzen, dann kann man auch wesentlich entspannter und effektiver an der eigentlichen Qualitätserhebung arbeiten.
Abgrenzung
Der gleich folgende Abzug meiner Antwort auf ein KPI-Strategie-Papier ist mit nichten als eine vollständige “Code Quality Metrics”-Strategie zu bewerten. Im Gegenteil. Meiner Meinung nach fehlen gerade im folgend gezeigten Diskurs wesentliche Elemente einer Qualitätserhaltung, -messung und -bewertung im agilen Sinne.
Nichtsdestotrotz belasse ich es bei meiner Antwort auf die u.g. KPI-Ideen. Der Blog-Artikel ist so schon lang genug. Darüber hinaus ist mein Ziel ja auch nicht das Aufzeigen aller Grundlagen zur Qualitätsmessung, sondern eben nur derjenigen, die sich immer wieder als “die üblichen Verdächtigen” hervortun.
In diesem Sinne, jetzt und hier:
“What you as a Developer, Tester, Manager or Leader should absolutely know about code quality measurement, indicators and their impact.”
Viel Spaß.
Quality Values
1. Code Base Maturity
- Ein stetig grüner CI-Build ist Indikator für die Stabilität der Software. Wir werden alle Buildergebnisse des CI nach Erfolg und Mißerfolg bewerten, um einen stabilen CI-Build als Grundlage zu gewährleisten.
Zu 1) Ich gehe davon aus, dass hier jeder rote Build mit einer Qualitätsminderung assoziiert wird. Im Gegenzug soll wohl hier ein stetiger Build-Erfolg ein Qualitätsmerkmal abbilden.
Es ist für das Ziel einer “Mature Code Base” für mich nicht direkt erschließbar, warum gerade ein stetig grüner Build von einer “erwachsenen Codebasis” Zeugnis tragen soll.
Vielmehr ist ein grüner CI ein Abbild der Sorgfaltskultur des Teams. Das allerdings auch nur, wenn eine rege Check-In-Kultur herrscht (in Kombination mit anderen Faktoren, selbstverständlich).
Eine strikte “Stay-Green”-Politik des Builds kann Gefahren mit sich bringen. Einerseits kann das Team zur Erhaltung der KPI auf Branches oder Shelves ausweichen. Andererseits ist auch eine “Check-In-Angst” in Folge des KPI-Drucks denkbar.
Das würde dem Qualitätsbestreben entgegenstehen, zumal eine lange “Vorhaltezeit” von Code-Änderungen zu größeren Commits, schwierigeren Merges und schlechterer Integration führen.
Es kann durchaus zur Folge haben, dass Commits auf die lange Bank geschoben werden, welches dann typischerweise am Ende der Iteration zu potenziellem “Commit-Stau” und Irritationen beim Merge führen kann.
Ich sehe diesem KPI mit äußerst kritischem Blick entgegen.
2. Architecture Conformance
- Eine automatisierte Prüfung der Abhängigkeitsbeziehungen der System- und Softwarekomponenten wird stetig mit den architektonischen Vorgaben korreliert. Somit lassen sich Abweichungen gegenüber der Systemarchitektur feststellen und beheben.
Zu 2) Die Annahme hier ist: geringere “Abhängigkeitsverletzungen” der Zielarchitektur können einen höheren Qualitätsspiegel darstellen.
Meines Erachtens ist das durchaus ein guter Indikator für Stringenz und Konventionstreue gegenüber der Zielarchitektur. Besonders beachtenswert ist es hier meiner Meinung nach, dass Architekturen durchaus einer “stetigen Bewegung” ausgesetzt sind – sich ergo im Laufe der Zeit verändern.
Unter dem Vorbehalt der individuellen Betrachtung der einzelnen Architekturbestandteile kann hier ein Messwert ein Indiz für ganzheitliche Systemkonzeption und -umsetzung sein.
Ich kann aus meiner Perspektive noch die Messung der Änderungs- bzw. Ergänzungsfrequenz der Architekturrichtlinien zweifelsfrei empfehlen. Es gibt Aufschluss über den “Architektur-Puls” – also der Beschäftigung mit der Gesamtkomplexität des Systems.
3. Standards and Best Practices
- Der gesamte Quellcode wird nach den üblichen Standards und Best-Practices wie Methodenlänge, Dateilänge sowie Code-Duplikate bemessen und bewertet werden.
Zu 3) Der Überbegriff ist hier für meine Begriffe mit zu viel Interpretationspotenzial behaftet. Mein Verständnis ist hier, dass die Pflege von Source Code nach “etablierten” Qualitätsmerkmalen wie z.B. Dateigröße oder Methoden-Länge eine allgemeine Verbesserung der Produkt-Qualität nach sich zieht.
Ich finde, eine Messung solcher “Best Practices” kann durchaus hilfreich sein und auch ableitbare Informationen über die Entwicklungs-Qualität geben.
Wichtig ist für mein Dafürhalten hier, dass die Werte für sich alleine zumeist kaum Aussagekraft mitbringen.
Vielmehr ist es so, dass zumindest Volumen-Indikatoren wie z.B. Anzahl der Code-Zeilen (LOC) oder Anzahl der Typdefinitionen (Class Count) in Korrelation gestellt werden müssen, um aus den einzelnen Metriken ein grobes Bild über das Pflegepflichtbedürfnis des Teams zu zeichnen.
4. Unit Testing
- Die Anzahl und Abdeckungsdichte von Unit-Tests ist ein weiteres, wesentliches Merkmal für die Messung der Software-Qualität.
Zu 4) Zweifelsohne sind lauffähige, positive Testprogramme für das Produkt ein Qualitätsmerkmal. Ich kann das Bestreben nach “Unit Testing” nur vollends unterstützen. Dennoch gibt es schon einige Punkte, die meiner Meinung nach einer genaueren Betrachtung bedürfen.
“Unit Test” ist ein weitläufiger, technisch geprägter Begriff, der auch einem breiten Spektrum von Test-Konzepten genügen kann.
Das ist meiner Meinung nach als Schwachpunkt zu deuten – ganz besonders, wenn es um die Erhebung von Metriken geht, bei der von Natur aus präzisere Messmöglichkeiten wünschenswert sind.
Ich rege zumindest eine weitere technische Unterscheidung zwischen Integrationstest und komponenten-orientiertem Funktionstest an. Während der Integrationstest (auf verschiedenen Ebenen) das reibungslose Zusammenspiel der Komponenten adressiert, ist der Funktionstest auf das korrekte funktionale Verhalten einer einzelnen Komponente – sprich: Klasse – konzentriert.
Im englischsprachigen Raum wird im Übrigen genau der Funktionstest oftmals als “Unit Test” bezeichnet, was sicherlich nicht zu einer klaren Abgrenzung der Test-Ansätze beiträgt.
Abgesehen von diesem – sehr weiten – Themenbereich kann ich den KPI mit einem freudigen, als auch einem kritischen Auge betrachten. Einerseits ist es wichtig und richtig, die Stabilität des Unit Tests im CI-Build zu beobachten. Andererseits ist eine ausschließliche Betrachtung der “Green-Rate” von Tests aus meiner Sicht mit schweren Deutungsvarianzen und einer latenten Abbildungsschwäche behaftet.
Es hilft aus meiner Sicht vielmehr, die Anzahl der Tests in Relation zum Code-Volumen zu beobachten. Daraus lässt sich tendenziell die Aktivität des Teams hin zu Testbarkeit und “Test-Awareness” beobachten.
Darüber hinaus ist vor Allem bei der “Stabilität” von Tests nicht nur deren Erfolgsrate wichtig, sondern auch deren “Anschlagsrate”. Ein Unit Test, der in Folge einer Regression fehl schlägt, ist für das Team als auch für das Produkt als Erfolg zu werten, weil er seinen Dienst der Überprüfung und Warnung verrichtet hat.
Ein weiterhin erwägenswertes Merkmal ist sicherlich die Dauer der roten Warnphase, in der ein Test fehlgeschlagen ist. Sie ist ein Zeichen für das verantwortungsbewusste Qualitätsempfinden des Teams. Eine kurze “Red-Response” ist ein hohes Gut für eine qualitätsorientierte, stetige Software-Entwicklungsmethodik.
Die zweite vorgeschlagene Metrik der “Code Coverage” ist – wie auch das Unit Testing selbst – eine Medaille mit zwei Seiten. Die Theorie der Testabdeckung besagt nämlich lediglich, dass der betroffene Code unter eine Testbedingung gestellt wurde. Das kann für eine strengere Qualitätsbetrachtung zuweilen schon nicht mehr hinreichend sein. Ich persönlich schätze die Aussagekraft einer Testabdeckung in Relation zum gesamten Code-Volumen als schwach und unpräzise ein.
Nichtsdestotrotz kann mit einigen Ergänzungen eine Testabdeckungsmessung nicht nur eine (begrenzte) Aussage über die Test- und Produkt-Qualität geben, sondern auch als anregender Katalysator hin zu einer manifestierten Testkultur betrachtet werden.
Eine hilfreiche Ergänzung ist die Definition und das Festhalten der Testabdeckungs-Ratio in Relation zu technischen und fachlichen Komponenten. Auf Grund einer technischen Architekturbetrachtung ließe sich eine technische Risiko- und Lebenszyklusbewertung vornehmen, die man in die Abdeckungsgewichtung einfliessen lassen kann.
Viel wichtiger ist aus meiner Sicht jedoch die Wertbetrachtung der fachlichen bzw. funktionalen Komponenten und deren Einbeziehung in die Testabdeckungszielsetzungen.
Eine tragende fachliche Kernkomponente kann durchaus mit intensiven Testbemühungen begleitet werden, um das Risiko einer Fehlfunktion sowie eines fachlichen Fehlverhaltens zu mitigieren.
Hier kann eine Testabdeckungs-Ratio von 98% oder mehr eine realistische als auch notwendige Zielbindung darstellen. Bei einer fachlichen Funktionalität geringerer Tragweite sowie technisch minder komplexen Szenarien wie zum Beispiel der Darstellung von Ergebniswerten kann eine (deutlich) mindere Testabdeckung vertetbar, ja sogar zweckgemäß sein.
Alles in Allem ist meine Perspektive zu diesem “KPI-Paket” eher positiv. Nicht zuletzt, weil es eine (kurzfristige) Anregung hin zu einer soliden, eigeninitiatorischen Testkultur darstellen kann.
Ich will dabei jedoch auf keinen Fall meine Bedenken in den Hintergrund rücken, sondern eher zur Erweiterung und stetigen Verbesserung im Bereich “Unit Testing KPI” ermutigen.
Quality Metrics And Impact
1. Impact Of Architecture Dependency Analysis
- Eine Einhaltung der Architektur-Vorgaben wirkt sich positiv auf die Erweiterbarkeit, Testbarkeit und Skalierbarkeit des Systems aus.
Zu 1) Alle drei nicht-fachlichen Werte können durch eine stringente Umsetzung von Architektur im komponenten-orientierten Sinne gestärkt werden. Bei der Testbarkeit kommt es sicherlich auch auf die Granularität der Verantwortungsteilung im OO-Design an.
Die Wirksamkeit zu verbesserter Skalierbarkeit hängt hierbei jedoch aus meiner Sicht in großem Masse von der Zielarchitektur ab, als ausschließlich von der Umsetzungstreue von Architekturvorgaben.
Eine meiner Meinung nach wichtige, jedoch unerwähnte Auswirkung ist die Bewältigung von fachlicher Komplexität sowie der daraus sich ergebenden verbesserten Wartbarkeit.
Bekannte und konventionalisierte Architekturmuster helfen, sich in komplexeren Interaktionen und Konstruktionen schnell wiederzufinden und zu orientieren.
2. Impact Of Unit Test Coverage
- Eine höhere Testabdeckung des produktiven Quellcodes gewährleistet Erweiterbarkeit und Testbarkeit des Systems.
Zu 2) Die Metrik der Testabdeckung stellt streng genommen wohl kaum eine Auswirkung auf Erweiterbarkeit dar. Auch Testbarkeit kann nur in geringem Maße ein direkter Wirkungsmechanismus von Testabdeckung sein.
Oft können mit wenigen Integrationstests viele Codebereiche abgedeckt werden, die keiner effektiven Erweiterbarkeits- oder Testbarkeitsbetrachtung genügen würden.
Im Sinne der nicht-fachlichen Qualitätsmerkmale ist meiner Meinung nach eine Testabdeckungs-Metrik ein äußerst schwacher Wirkhebel für Testbarkeit, Sicherheit und Stabilität.
3. Impact Of Compiler Warnings
- Durch eine konsequente Vermeidung von Compiler-Warnungen wird eine deutliche Senkung der allgemeinen Fehlerrate gewährleistet.
Zu 3) Unter der Berücksichtigung der vorgegebenen Einstellung “Treat Warnings as Errors” in C#-Projekten kann ich die Wirksamkeit auf verminderte Fehlerrate kaum einschätzen.
Da sie allerdings nur in besonderen Konstellationen (wie dem bekannten [Obsolete]-Warning) als hinderlich betrachtet werden kann, ist aus meiner Sicht eine besondere Beachtung der “Compiler Warnings” zumindest nicht von Schaden.
Indirekt kann man sogar durch einen strikteren Umgang mit Compile- und Buildergebnissen die Wachsamkeit und Wartungsverantwortung des Entwickler-Teams unterstützen. Insofern ließe sich zwar eine verbesserte Wartbarkeit ableiten, die jedoch weder direkt noch mit entscheidender Wirkungskraft einzustufen wäre.
4. Impact Of Duplicates
- Durch gezielte Vermeidung von Code-Duplikaten wird die allgemeine Fehlerrate gesenkt und die Wartbarkeit des Systems deutlich gesteigert.
Zu 4) Das Thema der Code-Duplikate ist im Entwicklungsumfeld sehr weit verbreitet und bekannt. Der gemeine Konsens ist hier, nach einer Vermeidung von Duplikaten zu streben, zumal sich dadurch Funktionalität dupliziert. Als Konsequenz steigt die Wartbarkeit, Stabilität und Sicherheit.
Ich kann im Allgemeinen eine Beobachtung der Code-Duplikate empfehlen. Die Metrik sollte in Relation zum Gesamtvolumen betrachtet werden.
Darüber hinaus ist es besonders empfehlenswert, eine “Abstandsmessung” von Duplikaten vorzunehmen. Hieraus kann in vielen Fällen auch der tendenzielle Verminderungswiderstand erkannt werden.
5. Impact Of File Size
- Durch die konsequente Begrenzung der Dateigröße einer Quelldatei kann die Komplexität des Systems begrenzt werden und die Wartbarkeit gesteigert werden.
Zu 5) Der direkte Bezug von Dateigröße zu fachlicher oder technischer Komplexität - wie sie hier erwähnt wird - erschließt sich mir auf den ersten Blick nicht verständniswirksam.
Vielmehr ist mein Eindruck, dass die Dateigröße als Volumen-Merkmal von Organisationseinheiten im Besonderen zur Wartbarkeit des Systems beitragen. Die Folge einer “überschaubaren” Organisationseinheit ist sicherlich der erleichterte Umgang mit dieser.
Eine Verringerung der Komplexität dieser Einheit - also der Klasse - ist bei distanzierter Betrachtung auch in vielen Fällen ersichtlich - jedoch nicht kausal auf einen restriktiven Umgang mit Dateigröße zurückzuführen.
Dennoch können kürzere Dateilängen sich indirekt auf die Komplexität vorteilhaft auswirken, zumal durch den “Organisationszwang” auch bedingt ein Aufbruch der Komplexität in einzelne Teilprobleme gefördert wird.
Insofern kann ich die Dateilänge als Qualitätsmerkmal schon nachvollziehen. Bezüglich der Aussagekraft der Metrik ist allerdings meiner Meinung nach Vorsicht und Augenmaß geboten.
6. Impact Of Length Of Method
- Eine strikte Begrenzung der Methodenlänge wirkt sich komplexitätsmindernd und damit qualitätssteigernd aus.
Zu 6) Die Länge einer Methode hat aus meiner Sicht eher einen indirekten - ja sogar schwachen - Bezug zur Komplexität. Im Allgemeinen sind “längere” bzw. “ausführlichere” Methoden weniger Komplex, sofern sie sich um eine Verantwortlichkeit kümmern.
Es ist schlußfolgernd eher das Single Responsibility Principle und die Separation of Concerns für die Minderung von Komplexität im Methodenbereich hilfreich.
Einen direkten Bezug bei der Methodenlänge sehe ich persönlich in der Wartbarkeit. Durch knappe und aussagekräftige Methoden lassen sich Aktivitäten schnell in fachliche Einzelkomponenten einteilen. Das wiederum fördert das Verständnis gegenüber der Fachlichkeit.
Eine Beobachtung der Methodenlänge als Qualitätsmerkmal ist sicher sinnvoll, wenn auch nicht so stark in der Aussagekraft wie z.B. die Verschachtelungstiefe.
7. Impact Of Nesting Depth
- Durch konsequente Eingrenzung der erlaubten Verschachtelungstiefe (Nesting Depth) wird eine deutliche Komplexitätsminderung erreicht.
Zu 7) Die Verschachtelungstiefe ist in meinen Augen ein starker Indikator für Komplexität struktureller, imperativer Programme.
Die sog. “Branches” und “Loops” sind essentielle Programmsteuerungs- und -verarbeitungselemente, die ein Indiz fuer gesteigerte Komplexität des gesamten Aktivitätsablaufes darstellen.
Je eher und treffender es dem Programmierer gelingt, fachlich aussagekräftige Abstraktionen anzuwenden, um so geringer fällt im Allgemeinen auch die Verschachtelungstiefe innerhalb einzelner Aktivitäten aus.
Die Metrik ist für mein Dafürhalten ein starker und relativ zuverlässiger Indikator für fachliche und methodische Komplexität.
Code Review
Jede Code-Erstellung oder -Änderung soll durch ein Code-Review von einem weiteren Entwickler beurteilt und für gut befunden werden.
Dieser letzte Punkt der Strategie-Eckpfeiler ist aus meiner Perspektive eines der effektivsten Qualitätssicherungsmaßnahmen. Mit Sicherheit sind auch die o.g. KPI-Metriken für eine Qualitätsaussage relevant.
Jedoch ist in vielen Fällen eine individuelle und eingehende Betrachtung der Quellen für die allgemeine Qualitätsverantwortung deutlich förderlicher.
Alleine durch die Aktivität des “Reviews” wird so meiner Meinung nach der Qualitätsanspruch als allgegenwärtige Zielsetzung in die Teamkultur integriert.
Dadurch wird das gemeinsame Qualitätsbild (und die daraus abzuleitenden Ziele) geschärft. Ein weiterer positiver Effekt ist die implizite Verantwortungsverteilung zu Code-Quellen. Sowohl der Verfasser als auch der Rezensent tragen Verantwortung für die Qualität und Konventionstreue des Codes.
Ein etwas schwächerer, aber dennoch zuweilen merkbarer Effekt ist in diesem Zuge auch der fachliche und technische Wissenstransfer, der mit der Rezension des Codes einhergeht.
In Summe ist meiner Meinung nach die Etablierung von Code Reviews ein sehr nützliches Mittel für den Erhalt von Qualitätsstandards.
Epilog
So. Hoch lebe die “Messbarkeit” von Code-Qualität. Wer es in diesem Blog-Artikel bis hierher geschafft hat, hat es auch verdient, eine kleine grundlegende Abschlußbemerkung zu lesen. Ich erlaube mir ein wenig “aus dem Nähkästchen” zu plaudern.
Es ist meiner Meinung nach besonders wichtig zu erkennen, dass die Code-Qualität nicht beim Code, sondern bei den Entwicklern des Codes beginnt. Gerade deswegen ist es bei einer Strategie zur Erhebung eines Qualitätsniveaus wichtig, auch individuelle Betrachtung der Fähigkeiten und Prinzipien der Entwicklungsmannschaft mit einzubeziehen.
Die hier gezeigte Diskussion über automatisierte Code-Metriken können allemals als Hilfswerkzeug oder Indiz für eine Qualitätsaussage dienen. Einem Anspruch der effektiven Qualitätsmessung werden automatisierte Code-Metriken mit Sicherheit ungenügend gerecht.
If you care about quality, care about your people.