Am 13. Oktober 2008 haben Peter Bucher und Golo Roden unter dem Titel "Noch Fragen, Bucher? Ja, Roden!" angekündigt, jeweils zum ersten eines jeden Monats einen Kommentar zu einem vorab gemeinsam gewählten Thema verfassen zu wollen. Heute, am 1. November 2009, ist es nun wieder so weit, und das Thema für diesen Monat lautet:
Wieviel Sinn machen Unit-Tests? [Der Anglizismus ist natürlich arg hässlich. Ich kann es aber auf meine Mitstreiter schieben, die sich diese Formulierung haben einfallen lassen.]
Die beiden haben mich netterweise gefragt ob ich dieses Mal wieder als "Gast-Mitstreiter" dabei bin, und so haben wir drei uns unabhängig voneinander im Vorfeld unsere Gedanken gemacht, wie wir diesem Thema gegenüberstehen.
Kommentare finden sich zeitgleich in ihren Blogs, folgend nun meine Meinung zu diesem Thema:
Ich hatte seinerzeit im Studium meinen Schwerpunkt auf die Theoretische Informatik gelegt. Damals hatte ich schon in der IT-Industrie gearbeitet und wollte an der Uni Dinge lernen, mit denen ich im Arbeitsleben nicht oder nur selten in Berührung kommen würde. Das sorgt dafür, dass ich meine eigene Diplomarbeit nicht mehr verstehe. Zu viele griechische Buchstaben, zu viele Beweise. Aber zum Thema: als theoretischer Informatiker gewöhnt man es sich sehr schnell an, Donald E. Knuth in etwa so anzubeten wie ein Apple-Jünger alles was weiß ist und nach Obst aussieht (oder schwarz — sofern Rollkragenpulli). Und in der Tat ist vieles, was Knuth geleistet hat, sehr bewundernswert. Vielleicht mit Ausnahme von TeX.
Aber zurück zum Thema: Knuth hat sich mit dem Thema Unit-Testing zumindest soweit beschäftigt, um eine kundige Meinung dazu abgeben zu können:
[T]he idea of immediate compilation and "unit tests" appeals to me only rarely, when I’m feeling my way in a totally unknown environment and need feedback about what works and what doesn’t. Otherwise, lots of time is wasted on activities that I simply never need to perform or even think about. Nothing needs to be "mocked up."
(Quelle:
http://www.informit.com/articles/article.aspx?p=1193856)
Das stellt mich vor ein Dilemma. Was Knuth sagt, hat Sinn (tschuldigung, Golo & Peter: macht Sinn). Und wenn es zunächst nicht sinnvoll klingt, dann muss ich eben meine Einschätzung ändern. Als regelmäßiger Verwender von Unit-Tests frage ich mich aber natürlich, ob ich all die Jahre auf das komplett falsche Pferd gesetzt habe?
Zu meiner und Knuths Ehrenrettung will ich versuchen, seine plakative Aussage ein wenig zu interpretieren. Manche Arten von Unit-Tests halte ich tatsächlich für Zeitverschwindung oder Eigen-Bauchpinselung des beteiligten Entwicklers. Dinge wie 100% Code Coverage sehe ich auch in sehr professionellen Projekten relativ selten. Immer wenn eine Klasse Standard-Getter und -Setter verwendet und als erstes dafür Unit-Tests der Machart "setze Eigenschaft auf 1, erwarte dass Eigenschaft den Wert 1 hat" geschrieben werden frage ich mich ob das tatsächlich das Ergebnis von Jahrzehnten Forschung in der Softwaretechnik ist.
Knuth begründet seine Abneigung gegenüber Unit-Tests in dem Interview insbesondere auf eine Anekdote, in der er ohne großartiges Testen (er meinte nicht einmal Unit-Tests) etwas Funktionsfähiges zu Stande gebracht hatte. Und in der Tat liegt es auf der Hand, dass bei bestimmter Projektgröße die Verwendung von TDD (Test-Driven Development) den Zeitaufwand beim Entwickeln erhöht. Hier vertrete ich vielleicht eine etwas extreme Meinung: Ich denke TDD macht die Softwareerstellung fast immer langsamer. Doch darum geht es hier gar nicht. Denn hat man ein entsprechendes Testsystem eingerichtet, ist die
Wartung und
Weiterentwicklung der Software deutlich einfacher. Insbesondere können so Regressionen schnell festgestellt werden. Code, der bestehende Unit-Tests verletzt, darf nicht einmal mehr eingecheckt werden. Man darf nicht vergessen dass Knuths Programm der Machart "meine Software kompiliert im ersten oder zweiten Anlauf" ein Beitrag für einen Programmierwettbewerb war. Eine spätere Wartung des Programms war also weder notwendig noch vorgesehen, jede Form von Unit-Tests hätte also nur Zeit (und den ersten Platz) gekostet.
Wo wir gerade beim Thema "Anbeten" sind: bei allen Vorzügen von Unit-Tests und TDD darf aber nicht vergessen werden dass jede Medaille zwei Seiten hat. Gerade Webanwendungen (mein Haupttätigkeitsgebiet) lassen sich häufig schwer testen, insbesondere wenn es um die Nutzerinteraktion und gegebenenfalls Browserbesonderheiten geht. Mit Tools wie
Selenium gibt es zwar hierfür schon Ansätze, aber das bloße Vorhandensein eines Tools bedeutet ja noch nicht dass alle Probleme aus dem Weg geschafft sind. Also: definitives 'Ja' zu Unit-Tests. Ebenfalls ein 'Ja' dafür, sich hohe Ziele (gerade in Hinblick auf Testabdeckung) zu setzen. Man denke jedoch stets an das bekannte Sprichwort: "Wenn man einen Hammer hat, sieht jedes Problem wie ein Nagel aus". Für nicht alle Programmiertasks ist Unit-Testing die einzige und unabdingbare Lösung, und nicht alles muss getestet werden (oder lässt sich testen). Die volle, beweisbare Wahrheit gibt es dann eben doch nur in der Theoretischen Informatik.