Wenn Software auf Qualität (s-Metriken) trifft – Teil 1

Ein Überblick gängiger Metriken zur Softwareverifikation, aus Sicht eines Entwicklers

Lässt sich Qualität von Software messen?

Vor allem in sicherheitskritischen Bereichen wie der Medizintechnik oder Automotive ist die Qualität von Software entscheidend. Vor allem dann, wenn Fehler in der Software zur Schädigung von Menschen führen kann, werden Entwicklungsprozesse benötigt, um Fehler beim Schreiben von Software zu verhindern und bereits gemachte Fehler aufzudecken. Da versteht sich der Wunsch von selbst, die Qualität von Software messen zu können. Aus diesem Grund werden Softwaremetriken eingesetzt. Nicht nur um Softwareteile mit geringer Qualität zu identifizieren, sondern auch um die Qualität der Software zu dokumentieren. Aber lassen sich die Qualität von komplexen Softwaresystemen wirklich mit wenigen Zahlen ausdrücken? Und bei welchem Wert muss, welche Metrik liegen um wirklich „gut“ zu sein? In diesem Beitrag werden wir uns mit einigen der gängigsten Metriken auseinandersetzen und nicht nur auf deren Funktionsweise, sondern auch auf deren Aussagekraft und Nutzen im Qualitätsmanagementsystem eingehen.

Lines of Code (LOC)

LOC ist sicher eine der trivialsten Metriken. Hierbei handelt es sich – wie der Name schon sagt – um die Zahl der Codezeilen. Dieser Wert kann z. B. auf eine Datei oder eine Funktion bezogen sein. Je nachdem welches Tool man verwendet, um diesen Wert zu berechnen, kann man unterschiedliche Ergebnisse erhalten. Wichtig ist, dass die Berechnungsvorschrift des LOC gleich ist, wenn verschiedene Softwaremodule miteinander verglichen werden sollen. So kann zum Beispiel festgelegt werden, ob und in welchem Umfang Kommentare mitgezählt werden.

Trotz der einfachen Berechnung lohnt es sich LOC für Funktionen und Dateien im Blick zu behalten. Auch wenn Code mit wenigen Zeilen nicht zwangsläufig besser ist, als einer der ein paar Zeilen mehr hat. Quetscht ein Entwickler gerne komplexe Berechnungen in eine Zeile, kann das deutlich unübersichtlicher sein, als wenn er die entsprechende Berechnung in mehreren Zeilen durchführt. Es sollte aber klar sein, dass bei Softwaremodulen ab einer bestimmten Länge, das Codereview deutlich erschwert wird. Es kann also durchaus Sinn ergeben, Richtwerte für LOC in den Kodierrichtlinien festzulegen. Wie hoch diese zu setzen sind, ist von vielen Faktoren abhängig, beispielsweise von der verwendeten Programmiersprache. Außerdem kann dieser Wert nur seinen Zweck erfüllen, wenn er auch tatsächlich überprüft wird. Zum Beispiel im Rahmen eines Code-Reviews oder durch die Wahl geeigneter Tools zur Erfassung von Softwaremetriken.

Beispiele für einen Grenzwert sind:

LOC pro Methode: 100

LOC pro Datei: 1000

Stellt sich nur die Frage, was tun, wenn dieser Wert trotzdem überschritten wurde? Das hängt von der jeweiligen Ursache ab:

  • Softwarearchitektur: Werden Source-Dateien zu groß, kann das unter anderem an der Softwarearchitektur liegen. Werden in einigen Modulen zu viele Funktionen zugeordnet, können sich diese schnell aufblähen. Aus diesem Grund lohnt es sich die Architektur immer wieder, auch während der Entwicklung, zu hinterfragen und ggf. anzupassen.
  • Kodierrichtlinien: Ein weiterer Grund für hohe LOC kann in den Kodierrichtlinien liegen. Entweder schreiben diese nicht klar genug vor wie der Programmierer seinen Code zu schreiben hat oder die Richtlinien werden nicht angewendet. Auch bei den Richtlinien bietet sich an, diese regelmäßig zu hinterfragen und anzupassen. Außerdem sollte bei Code-Reviews auch darauf geachtet werden, dass diese eingehalten werden. Der Entwicklungsprozess sollte an geeigneten Stellen den Status und die Qualität der Design-Outputs prüfen. Über Phasen- oder Meilenstein-Reviews soll sichergestellt werden, dass die Softwaremetriken erfasst und gegenüber ihren Annahmekriterien überprüft wurden.
  • Persönlicher Programmierstil: Ein weiterer Grund ist, dass es sich einfach um den Stil des Programmierers handelt. Jeder kennt diese genialen Programmierer, die in der Lage sind äußerst große Source-Dateien zu beherrschen, zumindest wenn sie den Code selbst verfasst haben. Das Problem zeigt sich oft erst dann, wenn Source-Dateien nach Jahren wieder angefasst werden. Nachdem der Autor entweder nicht mehr bei der Firma arbeitet oder völlig vergessen hat was er damals geschrieben hat. Daher ist es wichtig, dass sich auch die Genies unter den Programmierern an Vorgaben zur Codegröße halten, um es ihren Kollegen in Zukunft nicht unnötig schwerzumachen. Daher ist es wichtig die Mitarbeiter entsprechend zu schulen und die Vorgaben durch regelmäßige Reviews zu kontrollieren.

Ihr Ansprechpartner:

M.Sc. Björn Schmitz, Software Entwickler
E-Mail: schmitz@medtech-ingenieur.de
Tel.:  +49 9131 691 240
 

Benötigen Sie Unterstützung bei der Entwicklung Ihres Medizingeräts? Wir helfen gerne! Die MEDtech Ingenieur GmbH bietet Hardware-Entwicklung, Software-Entwicklung, Systems Engineering und Beratung aus einer Hand. Nehmen Sie Kontakt auf.

Kontakt aufnehmen

Coverage / Testabdeckung

Die Testabdeckung von Software ist sicherlich eine der am häufigsten verwendeten Metriken zur Softwareverifikation. Gleichzeitig wird jedoch Ihre Aussagekraft immer wieder infrage gestellt. Aus diesem Grund habe ich die Testabdeckung bereits in einem früheren Blogeintrag diskutiert, weswegen ich an dieser Stelle auch nicht zu sehr ins Detail gehen möchte. Zusammengefasst lässt sich sagen, dass die Abdeckung von Sourecode durch Unittests keinerlei Aussage über die Qualität der Tests oder der Software an Sich erlaubt. Von daher ergibt es nur bedingt Sinn hier einen Grenzwert festzulegen. Ein sehr geringer Wert kann allerdings ein Hinweis dafür sein, dass der Code noch einmal kritisch beleuchtet werden sollte. Eventuell hat man tatsächlich etwas Wichtiges beim Testen übersehen. Ist die Abdeckung aber tatsächlich so niedrig, weil der nicht getestete Teil einfach unkritisch ist, sollte man lernen auch mit geringen Zahlen leben zu lernen.

Will man hier aber unbedingt einen Grenzwert festlegen, würde ich diesen auf nicht mehr als 60 % festlegen.

Hier geht es zum Artikel über Testabdeckung

Zyklomatische Komplexität nach McCabe

Generell ist Code hoher Komplexität, schwerer zu beherrschen als solcher mit einer geringen Komplexität. Zum einen bedeutet Code mit hoher Komplexität einen höheren Testaufwand. Zum anderen ist komplexer Code in der Regel schwerer zu lesen, sodass die Wahrscheinlichkeit sinkt, bei Reviews Fehler zu finden. Die McCabe Metrik ist eine Möglichkeit, um die Komplexität von Funktionen zu berechnen. Das klingt soweit ähnlich wie bei der LOC-Metrik. Man könnte also auch hier auf den Gedanken kommen einen Richtwert festzulegen. Das Problem bei McCabe ist allerdings, dass eine hohe Komplexität nicht unbedingt schlecht sein muss. Oft gibt es gute Gründe dafür, warum ein Code komplex geraten ist. Auch muss Code mit hohem McCabe-Wert nicht zwangsläufig schlechter lesbar sein als einer mit niedrigem Wert.

Die Metrik kann allerdings ein Hinweis sein, welche Codeteile bei Reviews besondere Aufmerksamkeit benötigen. Wer allerdings hier einen Maximalwert festlegt, sollte sich nicht wundern, warum dieser Wert regelmäßig, überschritten wird, ohne dass sich hierdurch eine Maßnahme ergibt.

Beispiel für einen gängigen Grenzwert ist eine Komplexität von 15

Verschachtelungstiefe von Verzweigungen

Durch Verschachtelung von Verzweigungen wie if und switch lassen sich mit wenig Codezeilen, viele Funktionen umsetzen. Verschachtelung ist also generell nichts Schlechtes. Alternativen, um Verschachtlungen zu umgehen wären:

  • Viele Funktionen die sich nur in wenigen Zeilen unterscheiden
  • Verzweigungen in Funktionen auszugliedern

So oder so steigt bei geringerer Verschachtelungstiefe die Anzahl an Funktionen und somit die Größe des Codes. Ohne, dass dessen Komplexität steigt. Da auch eine Software mit vielen sehr einfach gehaltenen Funktionen unter Umständen schwer zu testen ist, kann es Sinn ergeben einige Verzweigungen zu verschachteln. Allerdings ist anzunehmen, dass sich ab einer gewissen Tiefe eine Anzahl an möglichen Funktionsdurchläufen ergibt, die für einen Reviewer kaum noch nachvollziehbar ist. Der Trick ist hier einen trade-off zu finden, zwischen Übersichtlichkeit und Codegröße. Eine durchschnittliche Verschachtelungstiefe zu messen ergibt vermutlich keinen Sinn. Sinnvoller ist es in den Kodierrichtlinien einen Maximalwert festzulegen. Wird dieser überschritten, sollte geprüft werden, ob es Sinn ergibt, den Code umzuschreiben.

Als gängiger Richtwert, für die maximale Verschachtelungstiefe, hat sich ein Wert von 4 bewährt.

Fazit

Aus Sicht eines Programmierers finde ich es schwierig sich bei der Bewertung von Qualität einer Software, nur auf Metriken zu verlassen. Die wenigsten Softwaresysteme ähneln sich untereinander genug, als das ein Vergleich über Softwaremetriken wirklich aussagekräftig wäre. Auch sagt das Einhalten von Grenzwerten bei Softwaremetriken, nicht viel darüber aus wie gut eine Software implementiert ist. Trotzdem möchte ich Metriken nicht generell schlecht reden. Das Einbinden von Softwaremetriken in den Entwicklungsprozess kann durchaus Vorteile haben. Das “Vermessen” der eigenen Software, kann ein Ansporn für Programmierer sein, Ihren Code zu verbessern. Zudem kann es dazu dienen, komplexere Softwaremodule zu identifizieren und festzulegen, welche Teile der Software beim Review von Implementierung und Design, besondere Aufmerksamkeit bekommen. Softwaremetriken bringen also durchaus einen gewissen Nutzen mit sich, den man aber nicht überbewerten sollte.

Auch interessant:

10 Jahre Medizintechnik. Erfahrungsbericht eines Software Teamleiters

Über 10 Jahre Medizintechnik. Was habe ich hier alles gelernt, welche Empfehlungen kann ich geben? Mit dieser Frage kam Goran Madzar auf…

Björn Schmitz

Seit Juli 2017 gehöre ich zum MEDtech-Ingenieur Team und bin hier vor allem als Firmwareentwickler tätig. Schon in kürzester Zeit konnte ich an vielen spannenden Projekten aus dem Bereich Medizintechnik, aber auch aus anderen Bereichen mitwirken.

Getagged mit: , , , ,

Schreibe einen Kommentar

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