TDD - kostet es wirklich Zeit?
Wer Software schreibt, der kennt, ab einem gewissen Level, sicherlich Unit-Tests. Und wer schon länger Software schreibt, weiß auch, dass es in vielen, vor allem älteren, Softwareprojekten kaum Tests gab.
Was mich aber um so mehr erstaunt: auch bei vielen neuen Projekten sind Tests nicht ausreichend eingeplant oder vorgesehen. Meist sind die Hauptargumente: Unit Tests können auch nicht alles testen, sind teuer, weil man lang dafür braucht und kaum aktuell zu halten.
Muss das sein? Stimmt das so? Ich weiß es nicht!
Was ich aber weiß, wenn man einen Test hat, macht einem das Leben leichter... Zwei Beispiele aus der Praxis:
1. Beispiel: Neue Berechnungen
ich schreibe aktuell ein Berechnungsmodell. Das ist recht komplex, und wir haben eine Fachabteilung im Haus, die sich damit schon eine Weile beschäftigt. Das alte Model sah ungefähr so aus: Nimm Eingabewert, verrechne ihn mit x anderen Werten und speichere es in die DB... ist ok, war aber von Jahr zu Jahr schwieriger zu warten.
Mein Model sieht vor, dass man "Formeln" hat, und diese Formeln dann eben mit den Angaben "füttert". Alle sinnvollen Formeln, die für die Berechnung gebraucht werden, kommen dann in meinen Berechner, und man kann den nach allen Zwischeneben der Berechnung "fragen" - easy interface: steck Datum rein, frag nach nem Key, krieg das Ergebnis...
Formeln arbeiten mit Vektoren... blablabla..
auf jeden Fall sinds jetzt schon 30 Formeln, einige einfacher, andere schon recht komplex - Tests dafür: 140. Die Tests sind noch nicht abschließend (mir fallen immer mal wieder irgendwelche Sachen ein, die man testen müsste... oder mein Konzept war doch nicht so gut, und ich musste was ändern)
Apropos Konzept ändern... ich musste einen Teil der Sachen umbauen, weil es doch nicht so geklappt hat, wie ich mir das vorgestellt habe... also: Änderung gemacht, Tests laufen lassen, Ergebnis: 6 Tests rot. War mir klar, das hatte impact auf anderes. Also die 6 Tests gefixt. Und der Rest? Funktionierte noch!
Mittlerweile sitze ich mit einer Frau der Fachabteilung gemeinsam am PC, wir schreiben den Test gemeinsam, ich implementiere die Formel mit, sie rechnet derweil die Sachen per Hand durch, und wir prüfen das Ergebnis. Erstaunlich: Sie kann kein Java, versteht aber meine Tests! Weil die Tests atomar sind, und die Formeln dadurch auch sehr überschaubar bleiben, kann sie auch das lesen! Wir finden gemeinsam Fehler, und sind hinterher sicher, dass das Zeug passt. Die Testsuite ist schon recht ausgefeilt...
was kostet mich das Test schreiben?
Effektiv? Nichts! Wie würde man denn, ohne Tests, vorgehen? Man schreibt eben so eine Berechnung, und dann? Muss ich das ja mal mit der Hand irgendwie testen... vielleicht mit der WebApp, in die das Ganze später eingebaut wird? Mit Daten, die da liegen? Kann man machen... dauert aber für jeden Use-Case ne ganze Weile... meine 140 Tests sind in weniger als 0.5s durch...! Da ist noch nicht einmal der Tomcat gestartet...
Und Testdaten brauch ich ja so oder so... aber wenn es sich ändert... alle Tests von Hand erneut durchführen? Ist das wirklich die schlaueste Lösung?
2. Beispiel
eine etwas ältere, aber immer noch in Entwicklung befindliche WebApp. Komplexes DB Model, komplexe Berechnungen, viel zu viele Use-Cases und viel zu komplexe Abläufe!
Ein Ablauf ist: Datei hochladen, speichern, umrechnen, abgeleitete Werte mit Formeln errechnen, plausibilisieren.
Man kann aber auch die Formeln ändern, und dann die hochgeladene Datei erneut umrechnen, Werte aus Formeln errechnen und plausibilisieren. Das dauert jedes Mal ca. 2-3 Minuten um so einen Test durchzuführen.
Natürlich hat was nicht funktioniert... die geänderten Formeln wurden nicht verwendet...
und auch neue Formeln wurden nicht angewandt!
Was mach ich? Ich mach es wie immer: laufen lassen, schauen, ändern, repeat... nach der 2. Iteration hau ich mir im Büro an den Kopf: Ich Depp! Ruf ich... und schreib einen Test...
weil ich schonmal eine TestSuite geschrieben habe, die eben die komplexe Struktur nachbaut (das ist schon eher ein Integrationstest... aber anders war das hier erstmal nicht zu fassen): Daten aus den Vorgaben laden, Formeln laden, eine CSV Datei zum durchrechnen laden, und dann das Ergebnis mit meinem erwarteten Ergebnis vergleichen.
Test1:
Test 1 war: erstmal schauen, ob die Formel, die ich gleich verändere überhaupt richtig rechnet.
Kosten des Tests: Bisserl copy paste von anderen Tests, überlegen, welche Formel ich teste, und was raus kommen soll... 2 Minuten!
Test2:
ich teste, ob die Formel, die ich gleich einbaue, nicht vorhanden ist: ist nicht vorhanden.
Kosten des Tests: copy paste vom ersten Test plus ein Assert: eine Minute
Test3:
ich teste, ob die neue Formel verwendet wird. Ich erstelle als eine neue Formel, füge sie nach dem ersten Durchlauf hinzu, lasse nochmal laufen und vergleiche
Kosten des Tests: copy past * 2 und eine Formel erstellen... eine Minute
Der Test war rot! ROT!
ROT
macht ja nix... ich schau in den Code, wo der Fehler passiert sein muss, ändere einen Aufruf einer ID und probiere es erneut: Test grün!
Test4:
ich teste, ob die veränderte Formel geht
gleicher Test wie Test3, nur die Formel sollte schon vorhanden sein: KOsten 1 Minute
insgesamt hab ich 10 Minuten gebraucht, das ganze ist nun fix und funktioniert...
kosten Unit Tests Zeit
Ja! Unbedingt! Aber nicht mehr, als man ohnehin braucht um zu schauen ob der Code funktioniert. Spätestens nach dem 2. Testlauf ist es billiger!
do it! Test it!
Congratulations @phash! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Vote for @Steemitboard as a witness to get one more award and increased upvotes!