Statische Code-Analyse mit “FixInsight”

Vorbemerkung: Mir wurde zu Test-Zwecken und zur Verwendung im Rahmen dieses Blog-Eintrags eine Lizenz von FixInsight kostenfrei zu Verfügung gestellt.

 

Was ist eine statische Code-Analyse – und wozu überhaupt?

Trotz – oder vielleicht auch gerade wegen – immer mächtiger werdender Entwicklungs-Werkzeuge werden Softwareprojekte zunehmend größer und komplexer. Damit einhergehend wird es ebenso zunehmend schwieriger, Fehler zu entdecken. Die statische Code-Analyse ist eine Möglichkeit, mit dieser wachsenden Problematik umzugehen. Sie ist, wie der Name schon sagt, ein statisches Verfahren, welches im Gegensatz zu den dynamischen Testverfahren die zu testende Software nicht ausführen muss, dafür jedoch deren Quelltext benötigt. Automatisierte Quellcode-Scanner sollen also helfen, die gesamte Codebasis schon während der Entwicklungsphase regelmäßig und insbesondere automatisch auf formale Mängel hin zu untersuchen. Dieser Ansatz ist nicht zuletzt aus wirtschaftlicher Sicht interessant: Defekte während der Entwicklung zu beheben ist bekanntlich deutlich günstiger als dies zu einem späteren Zeitpunkt zu tun.

Im Folgenden möchte ich zeigen, wie FixInsight dabei helfen kann.

Demonstration von FixInsight

FixInsight ist im Vergleich ein junges, aber dennoch stabiles Projekt. Es wird aktiv entwickelt, der federführende Entwickler sucht den Kontakt zu seinen Anwendern – zu uns also – und ist auf verschiedenen Wegen zu erreichen, unter Anderem auch in der Delphi-PRAXiS. Alternativ auch in der Google-Community “Delphi Developer”. FixInsight präsentiert sich als aktives und agiles Projekt, Ideen und Anregungen werden von den Entwicklern gern aufgegriffen, auf Fehlerberichte wurde bisher stets kurzfristig reagiert. Der Support für FixInsight hinterlässt einen rundum positiven Eindruck.

Als Code-Beispiel für die Analyse nutze ich ein internes Projekt, welches ich für Developer-Experts entwickelt habe.

Nach Installation integriert sich FixInsight in die IDE und kann aus dem Hauptmenü (Projekt -> Run FixInsight) heraus oder dem Kontext-Menü des Projekt-Verwaltung heraus gestartet werden.

Das Hauptfenster von FixInsight zeigt die Liste an vorhandenen Prüfungen und Messungen, jeweils mit Beispiel und Erläuterung sowie Eingabefeldern, falls eine Parametrisierung erforderlich ist. Einzelne Prüfungen lassen sich auch deaktivieren, was ganz praktisch ist, da man in der Praxis oft einzelnen Messungen eine größere Wichtigkeit einräumen wird als anderen. Zudem wird es üblicherweise einige Prüfungen und Messungen geben, die man regelmäßiger durchführen lassen möchte als andere.

Man sieht, dass die Liste sich aufteilt in “Warnungen” und “(Verletzung von) Konventionen”. Zu berücksichtigen ist, dass diese Messungen ein Angebot darstellen und keine Pflicht. Nicht jede Messung mag für jedes Projekt adäquat sein.

Es empfiehlt sich, diese Liste mal in Ruhe durchzugehen, die Beispiele anzusehen und sich zu verdeutlichen, welche Mängel jeweils entdeckt werden können.

Für einen ersten Versuch belassen wir es bei der Standard-Einstellung, in der alle Prüfungen und Messungen aktiv sind. Ein Klick auf die Schaltfläche “Run” rechts unten startet die Analyse (wahlweise für das gesamte Projekt oder nur für die aktuelle Unit). Die Befunde der Analyse werde im Nachrichten-Bereich der IDE in einem separaten Tab gesammelt:

Ein Doppelklick auf den jeweiligen Eintrag führt unmittelbar zur Stelle im Quellcode, an der der jeweilige Defekt diagnostiziert wurde. Üblicherweise wird auf den ersten Blick klar, was bemängelt wird und in der Mehrheit der Fälle sollte der Entwickler wissen, wie der die Fundstelle zu bewerten hat und was er gegebenenfalls zu tun hat, um den Defekt zu beseitigen.

In der Tat fördert so eine Analyse insbesondere am Anfang neue und mehrheitlich wichtige Erkenntnisse über den eigenen Programmcode zutage und ich empfinde statische Analysen als wertvolles Hilfsmittel, um den Programmcode im Griff zu behalten. Gerade diese nahtlose Integration eine Analyse-Werkzeugs in die IDE ist hierbei von besonderem Wert, da die Analyse damit Teil der routinemäßigen Arbeit werden kann.

Einige der Messungen lassen sich parametrisieren. Als Beispiel nehmen wir die Messung “C103”, die auch hier in der beispielhaften Liste der Befunde zu finden ist. Dabei geht es um die Anzahl an lokalen Variablen einer Methode. In diesem Fall habe ich den vorgegebenen Wert von “7” beibehalten und erhalte als Konsequenz daraus eine Liste aller Methoden mit mehr als sieben lokalen Variablen. Wer damit nicht einverstanden ist, weil ihm dieser Wert zu klein oder zu groß ist, der kann ihn entsprechend anpassen. Auf die Bedeutung der Messgrößen gehe ich etwas später noch genauer ein.

Ab und an passiert es, dass eine Stelle im Quellcode Kriterien erfüllt, die sie als möglichen Mangel klassifizieren lassen und dennoch wurde der betroffene Code vielleicht ganz bewusst genau so gestaltet. Das kann passieren und daher gibt es zwei Möglichkeiten, Warnungen nicht nur grundsätzlich zu deaktivieren, sondern punktuell im Quellcode: Zum Einen über einen Kommentar in genau der Zeile, die den vermeintlichen Mangel enthält: // FI:<NUMMER>, also zum Beispiel:

procedure RestartTimer;
begin
  FTimer.Enabled := False;
  FTimer.Enabled := True; //FI:W508 - Warnung W508 wird in dieser Zeile nicht generiertend;

Alternativ lassen sich über die bekannten Compiler-Schalter ganze Code-Blöcke von der Analyse ausschließen:

{$IFNDEF _FIXINSIGHT_}
procedure RestartTimer;
begin
  FTimer.Enabled := False;
  FTimer.Enabled := True;
end;
{$ENDIF}

Wichtig dabei ist jedoch, dass nur in sich vollständige Blöcke ausgeschlossen werden und der übrige Code auch ohne diese Blöcke syntaktisch weiterhin korrekt ist.

FixInsight speichert die Konfiguration der Prüfungen und Messungen im Projekt-Ordner, in einer Datei .ficfg, es handelt sich dabei um eine einfache XML-Datei.
Neben der Integration in die IDE verfügt FixInsight in der Professional-Edition auch über eine Variante für die Kommandozeile für automatisierte Analysen. Diesem Kommandozeilen-Tool ist dann u.a. die eben erwähnte Konfigurationsdatei zu übergeben.

Die Möglichkeiten einer statischen Code-Analyse empfinde ich als wertvolles Hilfsmittel. Wenn diese Unterstützung dann auch noch quasi auf dem Silber-Tablett präsentiert wird und sich so nahtlos in die IDE integriert, gibt es kaum noch Gründe, sich dagegen zu sperren. Jeder Erkenntnis-Gewinn über mein Projekt ist mir grundsätzlich willkommen. Dennoch sehe ich die Notwendigkeit, auch die Grenzen und Risiken einer statischen Code-Analyse aufzuzeigen.

Grenzen der statischen Code-Analyse

Wie eingangs erwähnt, ist die statische Code-Analyse ist ein gute Hilfe für Entwickler zur Vermeidung mancher (!) Qualitätsprobleme und potentieller Fehler. Es muss jedoch beachtet werden, dass solche Messungen zwar zur Qualität eines Software-Projektes beitragen können, ein hohes Maß an Qualität jedoch keinesfalls garantieren können. Die Qualität eines Software-Projektes wird durch viele Faktoren beeinflusst, von denen sich lediglich ein Teil über statische (oder dynamische) Analysen feststellen lässt. Das größte Manko der statischen Analyse ist die Beschränkung auf das Formale und die damit verbundene Unfähigkeit, auf Inhalte zu prüfen.

    Ein paar Beispiele:

  • Kommentare
    Was wird gemessen: Ist ein Kommentar vorhanden?
    Was wird nicht gemessen: Ist ein Kommentar korrekt und aussagekräftig?
  • Klassen-Design
    Was wird gemessen: Ist das Design kompakt?
    Was wird nicht gemessen: Ist die Abstraktion fachlich und technisch sinnvoll?
  • Parameter-Listen
    Was wird gemessen: Ist die Parameter-Liste kurz?
    Was wird nicht gemessen: Ist die Parameter-Liste spezifisch?
  • Tests
    Was wird gemessen: Abdeckung des Codes durch Tests
    Was wird nicht gemessen: Eignung der Tests, Fehler aufzudecken

Das ist gewiss nichts, was man der statischen Analyse vorwerfen könnte – man muss sich dieser Grenzen jedoch deutlich bewusst sein, wenn man mit den Mess-Ergebnissen hantiert und diese als Bewertungs- und Entscheidungsgrundlage nutzen möchte.

Einige der Messungen lassen sich parametrisieren, so zum Beispiel die Messung der Länge von Methoden. Hierfür ist es erforderlich, gewissenhaft geeignete Messgrößen zu bestimmen. Ist eine Prozedur mit 40 Zeilen bereits zu lang? Oder erst ab 60 Zeilen? Oder gar erst ab 150 Zeilen? Messen ohne geeignete Messgrößen ist nicht professionell, sondern irrational und unter Umständen sogar schädlich. Gerade bei dieser Messung tendiere ich dazu, einen hohen Wert als Schwelle zu definieren. Üblicherweise ist es mir gleich, ob eine Routine 15, 30 oder 75 Zeilen hat – das allein macht sie nicht per se “schlecht” oder “gut”. Wenn sie jedoch 200 oder mehr Zeilen hat, dann werfe ich wenigstens einen Blick darauf und überlege mir, was im konkreten Fall zu tun ist. Eine mögliche – in meinen Augen völlig legitime – Aktion kann es auch sein, bestimmte Messungen punktuell zu deaktivieren, weil ein Code vielleicht gerade mal so sein muss, wie er halt gerade ist. Entscheidend ist, die zu Grunde liegenden Messgrößen bewusst gesetzt und ggf. auch kritisch hinterfragt zu haben.

Statische Code-Analyse ist ein wertvolles Hilfsmittel, jedoch definitiv kein Wundermittel. Insbesondere gilt: Allein die Abwesenheit von Befunden garantiert noch lange keinen guten Code!

Alternative Werkzeuge

FixInsight ist ein gutes Werkzeug, welches sich in die Delphi-IDE integriert und dort dezent aber effektiv seine Arbeit verrichtet, ohne sich dabei in den Vordergrund zu drängen.
Lediglich der Vollständigkeit halber seien hier noch alternative Produkte gelistet:

Pascal Analyser (http://www.peganza.com/products.html#PAL)
CodeHealer (http://www.socksoftware.com/codehealer.php)
SourceMonitor (http://www.campwoodsw.com)
Delphi und RAD Studio (ab Professional-Edition) Audits und Metriken

Weitere Infos

Homepage und Download:
http://sourceoddity.com/fixinsight/

Online-Dokumentation:
http://sourceoddity.com/fixinsight/doc.html

Vortrag von der “CodeRage X” als Video:
http://sourceoddity.com/blog/2015/10/fixinsight-coderage-replay/

1
Daniel Wolf

About the Author:

Daniel Wolf ist als Software-Architekt im Miniatur Wunderland Hamburg tätig, war zuvor viele Jahre als technischer Berater tätig und spricht regelmäßig auf Konferenzen. Er betreibt das Forum "Delphi-PRAXiS". » Mehr Details zur Person
  Verwandte Blog-Einträge