Test, Debugging & Qualtitätssicherung

Wenn von ,Testen‘ gesprochen wird ist in der Regel das dynamische Ausführen von Software gemeint. Das ist jedoch nur ein Teilbereich. Weitere Disziplinen sind die statische Analyse von Software und das Test-Management. Unter dem Gesichtspunkt, dass die dynamische Ausführung in der Regel die aufwändigste Disziplin ist, lohnt sich auch ein Blick auf die anderen Disziplinen.

Am Ende bleibt noch das Debuggen, das Finden der Ursache für den Fehler. Auch hier lohnt ein Blick auf verfügbare Methoden und Werkzeuge, die anstelle von 'printf debugging' eingesetzt werden können.

GrafikProdukteTest

Test, Debugging & Qualtitätssicherung

Testen ist im Allgemeinen eine unbeliebte Aufgabe. Psychologisch ist das leicht zu erklären. Wir hätten alle lieber, dass wir für den vermeintlich abgeschlossenen Akt unserer kreativen Tätigkeit ein Lob bekommen. Ein positiv verlaufener Test hingegen zeigt uns auf, dass wir einen Fehler gemacht haben, und schlimmer noch, dass wir mit unserer Arbeit doch noch nicht fertig sind.

Nach dem Testen kommt das Debuggen. Der positive Test beweist lediglich, dass die Software in einer bestimmten Situation nicht das tut, was erwartet wird. Nun gilt es herauszufinden, was der Grund dafür ist. Dieser Vorgang wird als Debugging bezeichnet. Debugging ist ein immer wieder notwendiger Arbeitsschritt, dessen Aufwandsabschätzung schwierig ist. Bisweilen kann die Suche nach der Ursache eines Fehlers Wochen bis Monate dauern. Zum Beispiel, wenn Fehler nur sehr sporadisch auftreten und nur schwierig zu reproduzieren sind. Unter diesem Gesichtspunkt macht es häufig auch Sinn den Vorgang des Debuggens und mögliche Hilfsmittel genauer zu betrachten.

Grundsätzlich wird zwischen folgenden Formen des Tests und des Debuggings unterschieden:

  • Test-Management
  • Dynamische Ausführung
  • Statische Analyse
  • Debugging

Obwohl wahrscheinlich zu 90% die dynamische Ausführung als Testform genutzt wird, hat die statische Analyse eine mindestens gleichberechtigte Bedeutung. Der Vollständigkeit halber sei auch noch das Test-Management aufgeführt.

Test-Management

Test-Management bezieht sich überwiegend auf den oberen Teil des V-Modells. Hier wird z.B. der Grundstein für die Traceability zu den Anforderungen gelegt. Im Test-Management wird entschieden, was wann getestet werden muss/sollte und bei welcher Änderung welche Tests erneut durchgeführt werden müssen/sollten. Unterschätzt wird häufig das Potential des Testmanagements zur Effizienzsteigerung der Testaktivitäten an sich. In der Regel wird aus Unwissenheit der Abhängigkeiten auch nach vermeintlich kleinen Änderungen viel Testaufwand getrieben, da die Zusammenhänge und potentiellen Auswirkungen der Änderung unklar sind. Test Management hilft den tatsächlichen Aufwand für die Durchführung der Tests zu minimieren, bei gleichzeitiger Erhöhung der Qualität.

Dynamisches Testen

Hier wird der Code auf der realen Zielplattform oder auf Basis einer Simulation ausgeführt. Hier geht es um die Definition von Testsequenzen und den erwarteten Ergebnissen. Ziel ist immer auch, Tests mit geringem Aufwand wiederholen zu können und deren Ergebnisse zu dokumentieren. Häufiges weiteres Ziel ist die Automatisierung von Testabläufen in Form von Regression-Tests. Regression-Tests sind die Basis von Nightly Tests. Hierin wird der Hebel gleich an zwei Seiten angesetzt. Der Aufwand für die Durchführung der Tests minimiert sich. Mindestens genau so vorteilhaft ist die schnelle Rückmeldung von Fehlern. Bekommt der Entwickler die Rückmeldung eines Fehlers innerhalb von 24 Stunden zur Änderung befindet er sich gedanklich noch im Kontext der Änderung. Die Ursache des Fehlers ist naheliegend und langes Debugging nicht erforderlich. Kommt die Rückmeldung erst Wochen oder sogar Monate später fehlt der Bezug zur Änderung. In der Regel ist nun der Debugging-Aufwand (finden der Ursache) erheblich aufwändiger.

Statisches Testen

Beim statischen Testen handelt es sich um die statische Analyse des Codes. Der Code wird dabei nicht ausgeführt. Das hat den Vorteil, dass in sehr kurzer Zeit der gesamte Code analysiert werden kann. Auf Basis der statischen Analyse werden jedoch nur bestimmte Fehlerklassen abgedeckt. Aus diesem Grund wird es häufig nicht eingesetzt. Trotzdem ist es eines der effizientesten Vorgehen, um Fehler zu finden.  

Für folgende Fehlerklassen ist die statische Analyse prädestiniert. 

  • Speicherlecks
  • Zerstörung von Speicherinhalten
  • Zugriffe über NULL-Zeiger
  • Unsichere Zeigerarithmetik
  • Benutzung von Speicher nach Freigabe
  • Inkonsistente Freigabe
  • Konstruktor-/Dekonstruktor-Lecks
  • Fehlerhafte Verwendung von virtuellen Member-Funktionen
  • Arithmetische Fehler
  • Nicht initialisierte / unbenutzte Variable
  • Redundanter / überflüssiger Code
  • Division durch null
  • 32/64-bit Kompatibilitätsprobleme
  • Pufferüberläufe  

Debugging

Als Debugging wird die Suche nach der Ursache eines Fehlers bezeichnet. Debugging kann unter Umständen sehr zeitaufwändig sein. Vor Allem schlecht reproduzierbare Fehler lassen sich naturgemäß schlecht debuggen.

Treten schlecht reproduzierbare Fehler häufiger auf ist das immer ein ernstzunehmendes Warnsignal für eine unzureichende Software-Architektur.

Debugging-Hilfsmittel und Werkzeuge gibt es in Preislagen zwischen wenigen Hundert Euro bis hin zu mehreren Zehntausend Euro. Wir bezeichnen Debugging auch als Firefighting und raten die Investition in Fire Protection nicht zu vernachlässigen. Dann reichen in der Regel Werkzeuge im unteren Preissegment für effizientes Debugging. Für effizientes Fire Protection steht Architektur-Design an oberster Stelle.

 

Managements Interest

Investitionen in werkzeugunterstützte Tests sind derzeit in großer Mode und das ist grundsätzlich sehr löblich. Allerdings werden häufig nur Symptome bekämpft und nirgends kann schneller Zeit und Geld verbrannt werden, als im Test.

Wichtig ist, zu unterscheiden, wo die Ursache liegt und nur zu häufig ist diese in der über Jahre vernachlässigten Software-Architektur zu suchen. Ist das der Fall, werden Investitionen im Test, welcher Natur auch immer, nur signifikante Verbesserung bewirken. Qualität kann nicht in ein System hinein getestet werden. Bevor also in den Bereich Test investiert wird, sollte immer abgeklärt sein, dass nicht die SW-Architektur das Problem ist.

Momentan befindet sich das Software Engineering mitten in einem Paradigmenwechsel von der strukturierten Programmierung auf Basis von 3GL Sprachen (Third Generation Language) zur Modellierung auf Basis von 4GL Sprachen wie z.B. die Notation UML.

Die 4GL Sprachen haben bereits Notationselemente, die das Testen wesentlich vereinfachen. Sollten in Ihrer Entwicklung noch auf Basis einer 3GL Notation (C, C++ ...) programmiert werden, dann sollten Sie immer erst überlegen, ob nicht ein Umstieg zur MDSE (Model Driven Software Engineering) auf Basis einer 4 Gl Sprache in absehbarer Zeit sinnvoll ist. In diesem Fall ist immer anzuraten, erst MDSE einzuführen und dann in den Bereich Test zu investieren. Auf Basis z.B. der UML im Vergleich zu C/C++ können Testsequenzen mit halbem Aufwand spezifiziert und automatisiert werden. Damit hat sich der Umstieg auf MDSE bereits halb amortisiert und ist nachhaltig.

Häufig liegt der Fokus beim Testen auf der dynamischen Ausführung von Code. Dieses zu automatisieren verursacht relativ hohen Aufwand. Auch auf Basis von statischer Analyse lassen sich bestimmte Fehlerklassen wesentlich effizienter finden, dazu kommt, dass sich statische Analysen mit einem Bruchteil des Aufwandes automatisieren lassen und es hier sehr gute Werkzeuge für wenige 100 Euro gibt. (z.B. PC-Lint).

Wie sollten Sie vorgehen, wenn Sie in den Bereich Test investieren:

  1. Schließen Sie aus, dass Investitionen in den Bereich Test nur Symptome bekämpft. Wollen Sie Qualitätsproblemen entgegen wirken, unbedingt vorher ausschließen, dass Architekur-Defizite die Ursache sind.
  2. Programmieren Sie noch, dann gilt es zu klären, ob ein Umstieg zur Modellierung nicht sinnvoll ist. Hier ist grundsätzlich anzuraten den Umstieg zur Modellierung als ersten Schritt durchzuführen.
  3. Prüfen Sie, ob bereits statische Analysen durchgeführt werden und binden Sie diese fest in Ihre Prozesse ein. Der Aufwand dafür ist erheblich geringer, als die Implementierung von automatisierten dynamischen Tests, und erforderliche Werkzeuge sind tendenziell preiswerter.
  4. Erst dann sollten Sie in die Implementation von dynamischen Tests investieren. Und unterschätzen Sie nicht den Aufwand dafür. Grundsätzlich gilt die Regel, dass die Erstellung von dynamischen Tests und vor Allem deren Pflege den gleichen Aufwand verursacht, wie die Erstellung der Software an sich.
  5. Unterschätzen Sie nicht das Potential von Test-Management. 100% Testabdeckung ist weit entfernt von der Realität. Um so wichtiger ist es zu wissen, was wann wie getestet werden sollte.