Sind Unit Tests wirtschaftlich untragbar?

08.01.2012

Immer wieder höre ich die Aussagen “Unit Tests sind schön und gut, wir haben nur keine Zeit dafür.” Oder “Klar, man kann Tests machen, hauptsache, es nimmt nicht zu viel Zeit von der Arbeit weg” ??!!

 

Nur um Missverständnisse zu vermeiden: Tests macht man nicht zum Spaß oder aus Langeweile, die Tests stellen die Essenz, die abstraktester Form der Lösung dar!

 

Ich habe bis heute Schwierigkeiten damit, meinem Gegenüber zu erklären, dass er sich irrt. Ich WEIß es einfach aus Erfahrung, dass dies eine Milchmädchenrechnung ist. Keine ernsthafte Argumente gegen Tests würden bei einer tieferen Überprüfung standhalten. Die Pros übertreffen klar die Kontras. Aber wie soll ich etwas – für mich – Offensichtliches in Worte fassen? Wie soll ich etwas in ein paar Sätzen erklären, was ich in einem andauernden Prozess durch jeden NICHT (oder nicht richtig) geschriebenen Test gelernt habe? Oder durch jeden Aha-Effekt oder durch jeden stressfreien Release (kein Stress entsteht, wo kein Platz für Bugs existiert ;) )

 

Unit Tests sind für den Open Mind “selbsterklärend”: wenn der Bug in einem ungetesteten Code steckt, dann wird das zu einer “blinden” Fehlersuche führen, die Tage dauern kann und auf jedem Fall Geld und Ruf kostet. Wie lange dauert es, den Fehler in einem getesteten Codebasis zu finden, wo die Eingrenzung innerhalb von Sekunden erfolgt? Wie oft kommt es überhaupt vor, dass dieses Problem entsteht? Für mich schaut die Rechnung so aus:

 
Zeit_für_fehlersuche = Unproduktive_Zeit;
f(Unproduktive_Zeit) = Verschwendetes_Geld;
 
0->Zeit_für_fehlersuche(getesteter_Code)----------------------->Zeit_für_fehlersuche(ungetesteter_Code)---.....oo
 

Ok, ich glaube, ihr kennt jetzt meinen Standpunkt ;) Aber ich bin ja nicht die ultimative Maßstab dafür, wie man arbeiten sollte. Deshalb habe ich ein paar Artikel und Statistiken von klügeren Leuten zusammengesucht, bitte liest die auch.

 

Diese Infos habe ich bei stackoverflow gefunden:

Realizing quality improvement through test driven development: results and experiences of four industrial teams und hier eine Diskussion darüber.

The study and its results were published in a paper entitled Realizing quality improvement through test driven development: results and experiences of four industrial teams, by Nagappan and research colleagues E. Michael Maximilien of the IBM Almaden Research Center; Thirumalesh Bhat, principal software-development lead at Microsoft; and Laurie Williams of North Carolina State University. What the research team found was that the TDD teams produced code that was 60 to 90 percent better in terms of defect density than non-TDD teams. They also discovered that TDD teams took longer to complete their projects—15 to 35 percent longer.

“Over a development cycle of 12 months, 35 percent is another four months, which is huge,” Nagappan says. “However, the tradeoff is that you reduce post-release maintenance costs significantly, since code quality is so much better. Again, these are decisions that managers have to make—where should they take the hit? But now, they actually have quantified data for making those decisions.”

Es gab auch kleinere Experimente dazu wie z.B. Code Lab – TDD vs. Non-TDD

Over 3 iterations, average time taken to complete the kata without TDD was 28m 40s. Average time with TDD was 25m 27s. Without TDD, on average I made 5.7 passes (delivering into acceptance testing). With TDD, on average I made 1.3 passes (in two attempts, they passed first time, in one it took 2 passes.)

Now, this was a baby experiment, of course. And not exactly laboratory conditions. But I note a couple of interesting things, all the same.

Und weil ein Bild mehr als tausend Worte spricht: Die Kostenverteilung bei getesteten Code schaut ungefähr so aus
Testing Benefits

Tests schreiben ist einfach, der Ertrag ist riesig. Warum soll man also keine Tests schreiben? Sind wir wirklich unfehlbar, schreiben wir immer den perfekten Code? Seien wir mal ehrlich…Ich bin es sicher nicht und ihr auch nicht.

 

Und hier noch die obligatorische Buchempfehlung: The Art Of Unit Testing Das Buch ist wunderbar verständlich geschrieben mit echten Beispielen und guten Argumenten, warum und wie man testen soll.

Kick it on dotnet-kicks.de

Tags: , , , , ,
| Comments (17)

  • http://kostjaklein.wordpress.com Kostja

    Hallo Christina,

    wie Du richtig bemerkst, liegt die große Herausforderung tatsächlich darin, glaubhaft zu vermitteln und nachzuweisen, dass sich der Einsatz von Unit Test lohnt.

    Und es wird nicht einfacher dadurch, dass wir vielleicht auch akzeptieren müssen, dass dies nicht immer der Fall ist.

    Wahrscheinlich ist das auch die Ursache dafür, dass wir immernoch weit entfernt davon sind, dass Test als notwendiger Bestandteil von Software akzeptiert sind.

    Einige Interessante Gedanken dazu finden sich auch in diesem Artikel: Unit Testing Myths and Practices

    Die Diskussion geht weiter …

    Viele Grüße
    Kostja

  • Christina

    Hi Kostja,

    ich habe gewartet, dass “Die Diskussion weiter geht”, aber heute wird das wohl nicht mehr passieren :)

    Ich finde es schon komisch, dass etwas, was älter ist als viele Programmiersprachen, für die meisten Entwicklern unbekannt ist. Auch für sehr gute Entwickler! Ich sehe das Problem vor allem darin, dass es auch OHNE geht. Irgendwie.

    Gestern habe ich ein Tool (Teil von Typemock Isolator glaube ich) gesehen, das die Kosten/Nutzen-Rechnung erstellen soll. Es ist kein Freeware oder Open Source. Ich schätze, wenn das erste gute und freie Tool in diese Richtung erscheint, das könnte ein Durchbruch sein.

    Bis dann bleibt die gute alte Pionierarbeit :)

    Update: danke für den Link, scheint genau die Seite zu sein, die ich gesucht habe.

  • http://weblog.drescher-hackel.de Rene Drescher-Hackel

    Ich finde derartige Diskussionen immer wieder interessant. Beim Lesen hatte ich jedoch das Gefühlt, dass du in Tests das Seelenheil beim debuggen, sprich der Fehlersuche finden willst. Aber genau das sollten ja aus meiner Sicht Tests verhindern, sprich ich baue eine Erweiterung in meinen Code ein und kenne aber deren Tragweite nicht 100%-ig, der Test verrät mir aber, ob alle ursprünglichen Anforderungen noch umgesetzt sind, die Tests also grün oder rot sind. Ich habe Unittests bislang immer so verstanden, dass wenn der Test grün ist, mein Code auch fehlerfrei ist. Problematisch ist natürlich, wenn die fachliche Anforderung nicht richtig umgesetzt wurde, der Test falsch formuliert wurde – da können alle Tests grün sein – es wird nicht helfen.

    Die Notwendigkeit von Tests muss meines Erachtens in der Köpfen der GL reifen und dann entsprechend vom Entwickler umgesetzt werden. Leider tun sich viele Unternehmen damit sehr schwer.

  • Christina

    Dein Gefühl trügt, wenn ich einen Wunsch frei hätte, dann würde ich GAR nicht debuggen :D Seelenheil ist für mich nur ein weiteres Argument für Unittests.
    Wenn es um Erweiterungen geht, dann bin ich voll bei dir. Aber was ist mit den restlichen 90% der bereits vorhandenen Projekten? Da bleibt einem nichts anderes übrig, als zu versuchen, nachträglich eine immer größere Testabdeckung schaffen.

    Was die GL angeht, da bin ich andere Meinung. Ob man in einer Diktatur arbeitet oder freie Wille haben darf hängt natürlich von der GL ab. Über A. brauchen wir nicht reden. Also im Fall B. sind IMHO die Entwickler verantwortlich. Die GL will nur, dass es geht, und zwar auch morgen ;)

  • http://weblog.drescher-hackel.de Rene Drescher-Hackel

    Vorhandene Projekte Unittests zu unterziehen ist immer mit Zahnschmerzen verbunden und wird meiner Meinung nach nie 100%-ig sauber funktionieren. Was die GL angeht, muss es sehr wohl in deren Köpfen mit reifen, ihnen muss klar sein, dass eine Entwicklerstunde mit Tests eine andere ist, als die ohne Tests. Das es oft eine Milchmädchenrechnung ist, steht auf einem anderen Blatt Papier. Als Entwickler würde ich mich aber sehr zurück halten und Tests schreiben, wenn nicht klar von der Projektleitung dieses nicht gefordert ist. Hier muss es im ganzen Team/Unternehmen dann funktionieren. Ich erinnere mich gut an eine Diskussion im Netz, wo es darum ging, “Wie weise ich Tests auf der Rechnung aus” – da konnte man auch deutlich sehen, wo der Schuh eigentlich drückt.

    In diesem Sinne

  • http://phoop.blogspot.com Nino Martincevic

    “Wie weise ich Tests auf der Rechnung aus”

    Wieso sollte ich das tun?

    Muss mir ein Handwerker, der meine Wohnung tapeziert, extra ausweisen, dass er vorher Schutzfolie auf
    den Boden gelegt und sich die Hände gewaschen hat?

    Software, die nicht getestet wird, ist per se defekt und nicht professionell.
    Ist sie professionell, dann sollte man es auch den Profis überlassen, wie sie ihre Arbeit machen.

  • Florian Witteler

    Ich finde UnitTests extrem wertvoll und verzichte selbst bei kleinen Projekten nicht mehr darauf.
    Die gewonnene Sicherheit beim Refactoring ist aus meiner Sicht nur die eine Seite der Medaille. Viel mehr fällt aus meiner Sicht der Design-Aspekt ins Gewicht, wenn man TDD betreibt. Um den Code testbar zu machen, muss er zwangsläufig den gängigen Design-Prinzipien entsprechen – ein höchst willkommenes Nebenprodukt.

    Viel schwieriger finde ich, immer an die Sonderfälle zu denken. Da bin ich manchmal nicht kreativ genug. Manchmal tritt dann ein Fehler in Produktion auf, an den ich “im Leben nicht” beim Erstellen der Tests gedacht hätte. Auf die Sicherheit der unit-Tests möchte ich auf gar keinen Fall mehr verzichten.

    Prima finde ich ReSharper im Zusammenhang mit Visual Studio und nUnit. Dort kann man sogar die Tests debuggen.

  • Christina

    @Florian, du hast offensichtlich auch schon “Blut geleckt” :) Das Problem mit den abgefahrenen Szenarien wird sich schon legen, du wirst bald ein Gefühl dazu zu kriegen, worauf man besonders achten muss. Wichtig ist, dass du für alle diese unerwartete Fehler BEVOR du sie behebst einen Test erstellst. Dann folgst du auch dem Prinzip “Fool me once, shame on you. Fool me twice … you never fool me twice ;)”

  • Florian Witteler

    @Christina: Ja, genau so bin ich vorgegangen. Hat auch prima funktioniert, obwohl der kleine Teufel manchmal noch über die Schulter schaut in Form von ‘ich kann die eine Zeile Code auch schnell korrigieren, ohne extra dafür einen oder mehrere Tests zu schreiben’ ;-)

  • http://kleffels-software-blog.de Andreas Kleffel

    Wenn du mir erlaubts, deinen 6 Monaten alten Beitrag zu kommentieren, möchte ich folgendes äußern:

    Mit Unit Tests vs. Nicht-Testern ist es genauso wie mit ORMs vs. “Stored Procedure-Freaks”.
    Es ist der Fanatismus auf beiden Seiten, der eine Verständigung nicht möglich macht.

    Ich setze Unit Tests auch ein, mittlerweile auch erfolgreich. Aber dahinzukommen war kein leichter Weg. Unit Tests sind definitiv nicht leicht zu schreiben. Das Hauptproblem sind Abhängigkeiten bei Unit Tests. Man will nur eine Methode testen, muss man ggf. 100 Zeilen “Prepare” einschieben. Klar sollte das nicht so sein, aber wenn man mit Unit Tests anfängt, wird man wahrscheinlich keine leicht-testbare Codebasis haben.

    Wenn du das nächste mal mit einem Nicht-Unit-Tester diskutiert, der aber Unit Tests vielleicht schon einmal ausprobiert hat, versetze dich doch einmal in seine Lage. Seine Produktivität ist zunächst einmal GESUNKEN. Das erzeugt jede Menge FRUST.

    Ich glaube ich bin weiterhin absolut schlecht im Schreiben von Tests. Also konzentriere ich mich meistens auf die Tests, die absolut einfach zu schreiben sind, z.B. der Test von Regex oder APIs.

    Das ist ein Vorgehen, welches du jedem “Anti” empfehlen kannst.
    Letztendlich kann man aber auch von den “Antis” was übernehmen, denn Softwarequalität braucht viele Pfeiler. Unit Tests sind wichtig, aber kein Allheilmittel.

    Unit Tests können zwar (müssen aber nicht) Seiteneffekte finden. Aber wenn diese zu häufig auftreten, sollte der Programmierer vielleicht eher mal mit sich selbst hart diskutieren, warum diese auftreten (z.B. unkonzentriertes Arbeiten).

    Anderes Beispiel. Nehmen wir an, anstatt 40h Unit Tests werden 2x2h Code Reviews gemacht und haben den gleichen Qualitätseffekt.

    Wenn dein Programmierstil Test-first ist, ist das völlig OK und deutet deinerseits auf sehr gute Fähigkeiten hin. Aber akzeptiere doch auch noch andere Stile neben Dir.

    Oder mit einer Fußball-Metapher: Dir nützt das feinste Paßspiel und die beste Laufarbeit nichts, wenn du am Ende nicht ins Tor schießt. Manche sind nicht so versiert und gewinnen trotzdem irgendwie.

    Andreas

  • Florian Witteler

    Hi Andreas!

    Interessanter Beitrag zum Thema. Ich habe die selben Erfahrungen gemacht wie du. Ich beschreibe TDD immer als unbequemes Vorgehen. Wenn man eine Software peu à peu entwickelt, ohne diese zu testen, fallen einem die “100 Zeilen prepare” code gar nicht auf. Sprich: die versteckten Abhängigkeiten der zu testenden Komponente. Das macht TDD beileibe nicht einfach, erhöht aus meiner Sicht die Code-Qualität deutlich. Man wird sanft in die richtige Richtung gedrängt hin zu loser Kopplung, hin zu IoC etc.

    Aber ich stimme dir zu, manchmal frustriert die gesunkene Produktivität schon. Allerdings muss sollte in solchen Momenten die Frage erlaubt sein, ob es sich hierbei nicht um ein subjektives Gefühl handelt. Ich führe mir dann immer vor Augen führen, dass an ein Produkt Qualitätsansprüche gestellt werden und meine Tests mir dabei helfen, diese abzusichern. Ich glaube, das empfundene Gefühl der gesunkenen Produktivität liegt bei mir daran, dass meine Code-Flows durch häufigeres Nachdenken unterbrochen werden ;-)

    Florian

  • Christina

    Hi @Andreas, das Thema ist schon viele Jahre alt, da machen sechs Monate nichts aus :) Deine Tipps sind auf jedem Fall willkommen.
    Ich empfehle immer – wenn es um legacy code geht – genau deinen Weg: die Funktionalität zu testen, die man ohne Abhängigkeiten kapseln kann (wie Regex, Berechnungen, Code, der x bekommt und y liefert).
    Was die “Code reviews” betrifft, ich finde sie super, aber sie sind nicht wirklich eine echte Alternative: sie können nicht automatisch oder auf Knopfdruck wiederholt werden! Sie können eine gute Ausgangssituation liefern aber sichern nicht die Nachhaltigkeit. Der Code funktioniert heute. Aber funktioniert auch in 2 Monaten, nachdem ein paar neue Requests von anderen Kollegen implementiert wurden? Da hast du keine Garantie.. Verstehe mich nicht falsch, ich weiß, dass TDD alleine nicht ausreicht. Aber hilft schon mal ungemein.

    Florians Beschreibung ist genau die, die ich auch formuliert hätte: durch Tests wird dein Code unweigerlich übersichtlicher/modularer.

    Was die gefühlte Produktivität betrifft, hätte ich nur eine Frage? Wie hoch ist die Produktivität, wenn ihr die Zeit mit Bugsuche verbringt? Und der Frustpegel? Meiner steigt an solchen Tagen auf jedem Fall in die Höhe.

  • http://kleffels-software-blog.de Andreas Kleffel

    @Christina Ich steh mit meiner Meinung glaube ich zwischen allen Stühlen ;)
    Die Clean Code Developer mögen einen nicht, weil man zu wenig Unit Tests benutzt und die Coderevolverhelden (erst schießen, dann nachdenken) können mit einem auch nichts anfangen…

    Nur um das klarzustellen: Ich finde Unit Tests eine sehr gute Idee.

    ABER: manchmal haben die einen ROI von 5000% und manchmal doch eher von -50%

    Z.B. entwickele ich gerade einen Datenbank-Replikationsdienst. Das wäre ohne Unit Tests gar nicht machbar, denn da gibt es wahnsinnig viele Seiteneffekte. Da entwickle ich sogar – du glaubst es kaum – TEST-FIRST (Tada!).

    Aber wenn ich eine recht GUI- und Datenbank-lastige Anwendung programmiere, bringt das viel weniger. Regressionsfehler aufgrund von Seiteneffekten sind eher unwahrscheinlich. Da gibt es ganz andere Probleme.

    Deine Frage nach der langwierigen und frustrierenden Bugsuche stellt sich mir eigentlich selten, da an den Stellen wo ich keine Unit Tests einsetze, die anderen Qualitätsmaßnahmen (Nachdenken, Code-Reviews, manueller Test, gute iterative Entwicklungspakete) ausreichen.

    Der Kern meines Posts #1 war aber eigentlich ein ganz anderer: TOLERANZ.

    Ich habe letztes Jahr mal mit einem “älteren” “isolierten” Inhouseprogrammierer zu tun gehabt. Der wusste übertrieben gesagt gar nix von moderner “ordentlicher” Programmierung. Was ist OOP? Irgendsowas mit Klassen. Was ist SVN? Nie gehört.

    Aber erstaunlicher Weise hat der mit “einfachster” prozeduraler Programmierung sinnvolle Programme geschrieben, die für die Firma einen Wert hatten und deren Probleme gelöst haben.

    Sehr oft fehlt mir da einfach eine gewisse Toleranz gegenüber technisch vielleicht schlechteren Herangehensweisen, die aber durch die Vertrautheit teilweise kompensiert werden.

  • Christina

    “Die Clean Code Developer mögen einen nicht, weil man zu wenig Unit Tests benutzt und die Coderevolverhelden (erst schießen, dann nachdenken) können mit einem auch nichts anfangen…” Genau diese Pattsituation möchte ich wenigstens in meinem eigenen Umfeld entschärfen. Ich glaube, du bist auf dem selben Weg (auch wenn es noch unglaublich klingt, etwas Test-First zu bauen ;) )

    Ist wirklich schade, dass wir uns nicht bei #nossued treffen, wir könnten da diese Diskussion noch lange weiterführen.

  • Andreas

    Karsruhe ist etwas weit weg von mir.

    Aber ich glaube, ich bleib auch erst einmal bei meiner Meinung und nehme die “Schwachen” in Schutz ;)

  • Pingback: Testen war gestern … « Kostja’s .NETte Welt()

  • Matthias

    Wenn jemand sauber entwickelt und Tools wie Resharper richtig einsetzt, dann ist man mit Unit Tests genauso schnell wie ohne. Debugger starten und mit Breakpoints/Steps arbeiten ist zeitaufwendiger als ein sauberer Unit Test, denn ich dann debugge.
    Das Einfuehren von Unit Tests legt jede Menge Schwachstellen auf, die vorher nicht so bewusst sind, insbesondere beim Thema Design-Fehler. Daher ist das Kostenargument oft auf die Kosten von der Beseitigung von Fehlern im Legacy Code bezogen.
    Die Leute, die meckern, sind eher nicht bereit umzulernen und jeder Lernprozess dauert. Persoenlich finde ich es schwerer, die Unit Tests wartbar zu halten.

A baby has brains, but it doesn't know much. Experience is the only thing that brings knowledge, and the longer you are on earth the more experience you are sure to get.
[The Wonderful Wizard of Oz]
FireStats icon Powered by FireStats