Der Vorteil von Tests

Testen bedeutet, eine tatsächliche Funktion eines Produktes mit dem geplanten Ablauf zu vergleichen. Läuft alles wie beschrieben ab, gibt es Fehler? Da Software über eine Vielzahl von Funktionen verfügt, sind umfängliche Tests hier sehr zeitaufwändig (und schrecklich langweilig), wenn man sie manuell, zugleich aber ordentlich machen will. Es liegt nahe, diese aufwändige und langweilige Tätigkeit zu automatisieren: Softwaretests sind das Mittel dazu. Schreibt man zuerst den Test und danach den Code, dann spricht man von testgetriebener Entwicklung, kurz TDD.

In der Praxis schreibt man somit zwei Software-Artefakte: Eines enthält die zu testenden Eigenschaften, und ein zweites den Code, der diese bereitstellt. Natürlich schreibt sich auch Test-Code nicht von selbst: Ich rechne mit 10-25% Mehraufwand im Vergleich zu ungetestetem Code. Nicht wenige Auftraggeber scheuen diesen Aufwand, der ja am Ende auch Kosten bedeutet. Gängige Argumente gegen Testen sind:

  • Das machen wir später.
  • Dazu haben wir jetzt keine Zeit.
  • Das macht das Projekt zu teuer.
  • Damit kenne ich mich nicht aus.
  • Das nützt mir ja nichts.

Ein Beispiel aus der Praxis

Ich arbeitete an einem Portalprojekt, das zahlreiche Schnittstellen zu fremden Systemen aufweist. Das ist in meinen Augen eine ideale Voraussetzung für Tests, weil die Schnittstellenkomponente ein abgeschlossenes Modul ist, dessen Verhalten genau definierten Bedingungen genügen muss.

Der Zeitplan war eng und durchaus ambitioniert, dennoch entschied ich mich für eine testgetriebene Arbeitsweise. Das bedeutet, zunächst den Test zu entwickeln, und anschließend den Code dazu, der den Test erfolgreich ablaufen lässt. Die Konsequenzen waren:

  1. Ich hielt alle Anforderungen an den zu erstellen Baustein zunächst in Form von Testschritten fest. Lernte ich neue Anforderungen, so erweiterte ich meine Testschritte. Dadurch war ich stets im Bilde über alle Anforderungen, die an mein Arbeitsergebnis gestellt wurden.
  2. Der von mir entwickelte Code war so schlank wie möglich und erfüllte genau die gestellten Anforderungen. Es war nicht eine Zeile Code dabei, die ich für später vorgesehen hatte, ohne dass aktuell ein echter Bedarf daran bestanden hätte. Programmierer neigen dazu, ihre Arbeit für später zu verkomplizieren, mit der Begründung, dass so spätere Änderungen vereinfacht werden würden. Nicht selten kommt es nie zu diesen Änderungen.
  3. Mein Aufwand zum Durchführen der Tests blieb auch mit steigende Anzahl der Testschritte praktisch gleich. Das ist elementar wichtig, wenn 3 Minuten vor Abgabe noch schnell eine kleine Änderung reinkommt. Ich konnte es mir zeitlich stets leisten, die Qualität des gesamten Moduls sicherzustellen.

Da ich kaum eine Zeile Code mehr geschrieben hatte als unbedingt nötig, war ich mit meiner Zeitplanung unter der vorgegebenen Dauer geblieben, obwohl ich die Tests zusätzlich entwickelt hatte. Als das Fremdsystem später seine Spezifikation unbemerkt änderte, waren es die Tests, die die Abweichung als erstes klar beschrieben und eine Fehlerbehebung möglich machten. Der Kunde profitierte doppelt, denn erstens erfüllte das Modul alle Anforderungen und zweitens tat es das auf die einfachste mögliche Weise. Das erleichtert die spätere Wartung immens.

Was wurde aus den Gegenargumenten?

  • Das machen wir später.
    Dokumentation, Tests und Controlling gehören zu den beliebten Dingen, die man gerne aufschiebt. Die Erfahrung zeigt (auch hier), dass aufgeschobenes häufig überhaupt nicht erledigt wird. Zudem ist die Reihenfolge "Erst Code, dann Test" weniger hilfreich, da sie möglicherweise auch falsches Verhalten als erfolgreichen ausweist.
  • Dazu haben wir jetzt keine Zeit.
    Zwar bedeutet das Erstellen von Tests moderaten Mehraufwand, auf der anderen Seite reduziert es aber unnötige Arbeit. In diesem Fall war am Ende sogar ein geringer Zeitgewinn entstanden, weil ich keinen ungenutzten Code entwickelt hatte.
  • Das macht das Projekt zu teuer.
    Je früher ein Fehler entdeckt wird, desto geringer sind die Kosten, die zu seiner Behebung anfallen. Testen hilft, Fehler früh zu entdecken. Mein Ergebnis war bei der Übergabe sehr gut auf mögliche Fehlerquellen getestet.
  • Damit kenne ich mich nicht aus.
    Ein Test beschreibt die Eigenschaften eines Stücks Software, ohne darauf einzugehen, wie diese Eigenschaften erzielt werden. Tests sind daher häufig anschaulicher als das dahinter stehende Stück Software. Erfahrungsgemäß fällt es mit dem Entwicklungsprozess befassten Personen leicht, Tests zu verstehen. Keine Angst also!
  • Das nützt mir ja nichts.
    Eine Arbeit, die höhere Qualität bei geringerem Risiko und dadurch geringeren Kosten liefert, nützt immer demjenigen, der die Verantwortung dafür übernimmt. Sie warten ihre Software zum Festpreis? Investieren sie in Tests, um ihre Wirtschaftlichkeit zu erhöhen!

Ich möchte allerdings hinzufügen, dass ich zuvor schon auf diese Weise gearbeitet hatte und daher damit Erfahrung hatte. Die Erfolgschancen wären unter Zeitdruck geringer gewesen, wenn ich mich zunächst in die Technik des Testens hätte einarbeiten müssen. Auch gibt es Einsatzgebiete, in denen Testen zwar möglich ist, aber meiner Meinung nach nicht die gleiche Wirksamkeit entfaltet. (Zb mit Bezug auf die graphische Gestaltung von Benutzerinterfaces)