Automatisierte Tests: Unit-Tests

Bekanntlich sind Softwaretests sehr teuer. Erst einmal verursacht das Testen selbst schon viel Aufwand. Und dann ist es zumindest bei guten Testern noch schlimmer, weil dabei eventuell Fehler gefunden werden, deren Behebung dann auch noch einmal teuer ist.

Nun ist leider das Ignorieren von Fehlern auch teuer, wenn die Software für einen ernsthaften Zweck eingesetzt wird. Man sagt, daß es umso teurer wird, je später der Fehler gefunden wird. Das fängt teilweise schon vor der eigentlichen Entwicklung des entsprechenden Features an. Wenn man das falsche entwickelt oder nur auf das falsche Konzept setzt, dann wird der Aufwand, daraus am Ende eine brauchbare Lösung zu machen, auch groß. Das trifft auch bei agilen Entwicklungsprozessen zu.

Ein anderes, gar nicht so seltenes Ärgernis sind Fehler, die schon einmal behoben waren und irgendwann wieder auftauchen. Wie kann das passieren? Es ist leider so, daß man beim Arbeiten Fehler macht, außer vielleicht Donald E. Knuth bei der Entwicklung von TeX, das ja praktisch komplett fehlerfrei ist.

Hier geht es um automatisierte Tests, insbesondere während der Entwicklung, also vor allem Unit-Tests. Eine ganz neue Erfindung sind diese automatisierten Unit-Tests nicht. Schon in den 90er Jahren war es bei in C geschriebener Unix- und Linux-Software recht üblich, daß man nach
./configure
make
ein
make check
oder
make test
aufrufen konnte. Das gibt es so übrigens auch heute noch. TeX und Metafont von Donald E. Knuth haben den sogenannten „Trip“/“Trap“-Test, der recht rabiat vorgehen soll, also versucht, die Software „gegen die Wand zu fahren“.

Aber heute werden diese Unit-Tests durch leicht verfügbare Frameworks, wie z.B. JUnit für Java unterstützt oder sind sogar schon Teil des normalen Lieferumfangs der Sprache, wie bei Ruby. Sinnvoll ist es bei Projekten, die die entsprechende Infrastruktur haben oder haben können, diese Tests regelmäßig automatisch auf den neuesten Stand aus dem Repository anzuwenden und Fehler zu melden. Vielleicht sogar mit einer roten Fußgängerampel beim Ausgang des Gebäudes, in dem die Entwickler der Software arbeiten? 😉

Andererseits macht es auch Spaß, wenn die Unit-Tests nach einer heftigen Änderung durchlaufen und alles grün ist, sogar die Fußgängerampel bei der Tür.

Nun ist die Frage, wie man dieses Mittel einsetzt, wie weit man automatisiserte Tests treibt und wann man sie entwickelt.

Erfahrungsgemäß werden Unit-Tests gerne bei der Zeitabschätzung eingeplant. Später wird dann die Zeit knapp und sie werden dann doch weggelassen. Es gibt eigentlich häufiger zu wenige als zu viele solcher Unit-Tests. Warum kann es überhaupt zu viele geben? Natürlich wird es irgendwann lästig, wenn das Ausführen der Unit-Tests mehrere Stunden dauert und wenn die Entwicklungsaufwände für die Tests unverhältnismäßig groß werden. Wobei ich in manchen Fällen 60% des Aufwands für die Tests und 40% für die eigentliche Funktionalität noch für angemessen halte. Das Problem ist aber, daß man einige Dinge nur mit sehr großem Aufwand automatisiert testen kann. Damit geht die Flexibilität verloren. Änderungen, die man mal eben macht, verhindern schnell mal, daß die Tests erfolgreich durchlaufen. Dann werden sie mal kurz „vorläufig“ deaktiviert, auskommentiert oder sogar ganz gelöscht, weil sie nicht mehr anwendbar sind, ohne daß die entsprechende neue Funktionalität Tests bekommt. Oder man erinnert sich, wie mühsam es war, die Tests zu schreiben und verzichtet dann deshalb auf eine an sich sinnvolle Änderung.

Daher würde ich empfehlen, automatisierte Tests für Funktionalitäten, die sich noch oft ändern, eher in einer späten Phase des Projekts zu schreiben. Dagegen lohnt es sich für Basisfunktionalitäten, von denen im Gesamtsystem viel abhängt und die sich wahrscheinlich kaum ändern, höchstens erweitert werden, sehr umfangreiche Unit-Tests.

Schön ist es, wenn man beim Beheben von Fehlern „Test Driven Development“ praktiziert, also einen oder mehrere Unit-Tests schreibt, die eigentlich erfolgreich („grün“) durchlaufen sollten, aber die aufgrund des Fehlers scheitern. Das schaut man sich an, es muß wirklich „rot“ werden, und zwar wegen des Fehlers, den man gerade behebt, sonst ist der Test falsch. Dann behebt man den Fehler und am Schluß läuft der neue Test erfolgreich durch. Weil man ihn dann in die Menge der automatisiert aufgerufenen Unit-Tests aufnimmt, ist die Wahrscheinlichkeit, daß derselbe Fehler bei einer späteren Änderung wieder hereinkommt, sehr verringert worden.

Share Button

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*