Eine Einführung in Test Driven Development (TDD) gibt es in der
einhundertdritten Folge des Anwendungsentwickler-Podcasts. TL;DR
Bei Test-Driven Development (TDD) schreibst du automatisierte Tests
vor dem Produktivcode und entwickelst in kleinen Schritten. Jeder
neue Test muss zunächst aus dem passenden Grund fehlschlagen, bevor
du ihn mit möglichst wenig Code erfolgreich ausführst und den Code
anschließend überarbeitest. Dadurch entsteht ein Testnetz, das
Fehler nach Änderungen aufdeckt und einen modularen Softwareentwurf
fördert. Aus meiner Praxis zeige ich dir auch, wie du passende
Testfälle findest und welche Hürden beim Einstieg sowie bei
bestehendem Code auftreten. Kapitelmarken [00:00:00] Einstieg in
Test-Driven Development [00:01:33] Meine Masterarbeit und NATUnit
[00:02:31] Was ist testgetriebenes Entwickeln? [00:03:56] Der
klassische TDD-Zyklus [00:05:11] Die TDD-Ampel und kompilierbare
Tests [00:07:09] Tests als Sicherheitsnetz beim Refactoring
[00:08:01] Regressionen nach Änderungen [00:09:03] Warum Tests aus
dem richtigen Grund fehlschlagen müssen [00:12:11] Mit möglichst
wenig Code einen Test erfüllen [00:13:33] Refactoring am Beispiel
einer Wurzelfunktion [00:14:45] YAGNI und kleine
Entwicklungsschritte [00:18:05] Schnelles Feedback beim
Überarbeiten von Code [00:20:30] Mein erweiterter TDD-Zyklus
[00:21:39] Aussagekräftige Fehlermeldungen [00:24:16] Auch Testcode
refaktorisieren [00:26:52] Hürden und zusätzlicher Zeitaufwand
[00:28:28] Legacy Code und schwer testbare Abhängigkeiten
[00:30:09] Vorteile für Testabdeckung und Softwareentwurf
[00:32:49] Zeit sparen und mit Code experimentieren [00:35:37]
Praktisch mit TDD anfangen [00:37:06] Erste Testfälle und der Happy
Path [00:38:06] Grenzwerte und Fehlersituationen testen [00:39:50]
Testfälle aus Äquivalenzklassen auswählen [00:41:40] Was ist ein
Regressionstest? [00:43:00] Video und Bücher für den Einstieg
[00:46:41] Weiterführende Literatur und meine Masterarbeit
[00:48:07] TDD in der Ausbildung und im Arbeitsalltag Inhalt Was
ist Test Driven Development (TDD)? Beim TDD werden die Tests vor
dem Produktivcode geschrieben. Wie läuft der TDD-Zyklus ab? Red,
green, refactor. Der Test muss fehlschlagen, dann wird er so
einfach wie möglich grün gemacht, dann wird refaktorisiert. Was ist
der erweiterte TDD-Zyklus? Red, optimize failure message, green,
refactor, refactor tests. Zusätzlich zum normalen Zyklus wird Wert
auf sprechende Meldungen bei Fehlschlägen gelegt und auch der
Test-Code explizit refaktorisiert. Wie kann man TDD mit
Integrationstests kombinieren? Wie in GOOS* beschrieben: Zuerst
Integrationstest schreiben, der längere Zeit fehlschlägt, und dann
Schritt für Schritt mit Unit-Tests auf grünen Integrationstest
hinarbeiten. Warum heißt TDD auch Test Driven Design? Weil sich das
Design der Anwendung erst beim Programmieren ergibt. Was sind
Vorteile von TDD? Tests werden nicht vergessen. Hohe Testabdeckung
des Produktivcodes. Gute Modularisierung des Codes durch
Fokussierung der Tests. Hohe Testbarkeit des Codes (wenig
Abhängigkeiten). Langfristig Zeiteinsparung bei der
Weiterentwicklung, da Regression sofort erkannt wird. Experimente
und Refactorings werden durch Testnetz erst ermöglicht. Was sind
Nachteile von TDD? Umstellung beim Entwickler nötig. Zunächst
höherer Zeitaufwand. Legacy Code ist meist nicht gut testbar. Wie
findet man Testfälle? Start mit "Happy Path" übliche
Geschäftsvorfälle einfachste Fälle Edge-Cases/Grenzwerte
Sonderfälle Was sind Äquivalenzklassen? Werte, deren Verwendung in
Tests zum Durchlaufen des gleichen Pfades im Code führen und damit
nicht zusätzlich getestet werden müssen (Beispiel "positive Zahl" 5
und 322). Was ist ein Regressionstest? Regressionstest stellen
sicher, dass Abweichungen vom bisherigen Verhalten (Regression)
schnellstmöglich erkannt werden. Wie steigt man am besten in TDD
ein? Nicht lange schnacken (lesen), Kopp in' Nacken (coden)!
Einfach machen! Am besten mit Code Katas. Literaturempfehlungen Zum
Einstig schau dir mal diese perfekt auf die Begleitmusik angepasste
Implementierung der Kata "Prime Factors" von Uncle Bob an: Prime
Factors Kata in Ruby, Flower Duet, Lakme' Zum Thema TDD empfehle
ich zunächst das "Original" Test Driven Development: By Example*
von Kent Beck, der TDD erfunden hat. Es ist voll mit Beispielen,
gut verständlich und auch nicht allzu lang. Das Buch ist zwar schon
ein paar Tage älter, aber immer noch meine Empfehlung zum Einstieg.
* Etwas moderner geht es zu in Professional Test Driven Development
with C#*. In den Links habe ich auch meine Rezension des Buches
verlinkt. Dort erfährst du noch mehr darüber, warum ich das Buch
empfehlen kann. * Zuletzt noch ein modernes Buch zum Thema testen
und TDD: Pragmatic Unit Testing in Java 8 with JUnit*. Darüber habe
ich schon eine ganze Podcast-Episode aufgenommen und auch eine
Rezension geschrieben (siehe Links). * Falls du schon
fortgeschritten bist, kann ich wärmstens Growing Object-Oriented
Software, Guided by Tests* empfehlen. Das Buch hat mein Verständnis
von TDD noch einmal grundlegend erweitert und mich nachhaltig
geprägt. Ein tolles Buch, das auch den erweiterten TDD-Zyklus
beschreibt und über einfache Unit-Tests weit hinaus geht. * Und
falls du mal lesen willst, wie ich ein Testframework testgetrieben
entwickelt habe, kannst du dir hier den entsprechenden Teil meiner
Masterarbeit herunterladen: NUNIT: A Unit-Test-Framework for
Natural. Links Permalink zu dieser Podcast-Episode RSS-Feed des
Podcasts Regressionstest – Wikipedia Rezension: Professional Test
Driven Development with C# von James Bender und Jeff McWherter
Rezension: Pragmatic Unit Testing in Java 8 with JUnit von Jeff
Langr Pragmatic Unit Testing in Java 8 with JUnit (Buchclub)
Rezension: Growing Object-Oriented Software, Guided by Tests
(Freeman/Pryce) Zusammenfassung TDD aus meiner Praxis In meiner
Masterarbeit habe ich untersucht, wie testgetriebenes Entwickeln
die Qualität von Software beeinflusst. Dafür habe ich bestehenden
Code überarbeitet und anhand von Codemetriken geprüft, wie er sich
verändert. Dabei ließ sich eine bessere Codequalität feststellen.
Außerdem habe ich NATUnit für die Programmiersprache NATURAL
entwickelt, wobei ich mich an JUnit und NUnit orientiert habe. Das
Framework ist seit Jahren in meinem Betrieb im Einsatz. Tests vor
dem Produktivcode schreiben Bei Test-Driven Development, kurz TDD,
schreibst du zuerst einen automatisierten Test für das gewünschte
Verhalten. Anschließend entsteht der Produktivcode, der diesen Test
erfüllt. Die Tests treiben dabei auch den Entwurf deiner Software
voran, weil du schon beim Schreiben über die Schnittstellen und das
erwartete Verhalten nachdenken musst. Der klassische TDD-Zyklus
Red: Du schreibst einen Test und führst ihn aus. Er muss zunächst
fehlschlagen, weil das gewünschte Verhalten noch fehlt. Green: Du
schreibst so wenig Produktivcode wie nötig, damit der neue Test
erfolgreich durchläuft. Bereits vorhandene Tests müssen weiterhin
erfolgreich sein. Refactor: Du überarbeitest den Code, während die
Tests das bisherige Verhalten absichern. Beispielsweise entfernst
du doppelte Inhalte oder extrahierst eine Methode. Bei einer
Sprache mit Compiler kann davor ein weiterer Zustand auftreten: Der
Test lässt sich noch gar nicht kompilieren, weil eine Klasse oder
Methode fehlt. Diese sogenannte gelbe Phase endet, sobald du die
nötigen Strukturen angelegt hast. Danach kannst du den Test
ausführen und sein Fehlschlagen prüfen. Warum ein Test zuerst
fehlschlagen muss Wenn du einen neuen Test einmal fehlschlagen
siehst, kannst du prüfen, ob er auf das fehlende Verhalten
reagiert. Eine Prüfung wie 1 == 1 bleibt bei jeder Änderung am
Produktivcode erfolgreich und erzeugt dadurch falsche Sicherheit.
Auch der Grund für das Testergebnis muss nachvollziehbar sein.
Erwartest du bei einer ungültigen Eingabe eine bestimmte Exception,
gehört deren Typ zur Prüfung. Eine zufällig auftretende
Datenbank-Exception würde eine andere Ursache anzeigen. Durch
automatisierte Tests erkennst du Regressionen: Bereits
funktionierendes Verhalten fällt nach einer Änderung aus. Das kann
auch eine andere Klasse betreffen, die vom geänderten Code abhängt.
Ein Regressionstest prüft, ob das bisherige Verhalten weiterhin
funktioniert, und deckt unerwünschte Abweichungen auf. Diese
Begriffe können dir auch im Fachgespräch begegnen. Kleine Schritte
und YAGNI Beim ersten Test einer Wurzelfunktion kannst du prüfen,
ob die Wurzel aus 1 den Wert 1 ergibt. Für diesen Test reicht
zunächst return 1. Weitere Testfälle verlangen nach zusätzlichem
Verhalten. Beim anschließenden Refactoring entwickelst du den Code
weiter und ersetzt wiederholte Fallunterscheidungen durch einen
passenden Algorithmus. Mit YAGNI, ausgeschrieben You Ain’t Gonna
Need It, konzentrierst du dich auf das Verhalten, das deine
aktuellen Anforderungen verlangen. Zusätzliche Funktionen und
Abstraktionen für vermutete spätere Wünsche kosten Zeit und machen
den Code komplexer. Gerade beim Einstieg übst du diese Baby Steps,
damit du auch bei schwierigen Problemen in einem komplexen System
schrittweise vorgehen kannst. Mit Erfahrung kannst du größere
Schritte wählen. Nach jeder Änderung gibt dir die Testsuite
Rückmeldung über das geprüfte Verhalten, sodass du einen
fehlerhaften Schritt zurücknehmen und einen anderen Weg
ausprobieren kannst. Mein erweiterter TDD-Zyklus In meiner Praxis
ergänze ich den klassischen Ablauf um zwei Schritte: Red: Den neuen
Test fehlschlagen lassen. Optimize Failure Message: Prüfen, ob die
Fehlermeldung beim Suchen nach der Ursache hilft, und sie bei
Bedarf verbessern. Green: Den Test mit möglichst wenig
Produktivcode erfolgreich machen. Refactor: Den Produktivcode
überarbeiten. Refactor Tests: Auch den Testcode überarbeiten. Bei
einer Meldung wie "Value is False" fehlt dir der fachliche
Zusammenhang. Eine Meldung wie "Der Kontostand darf niemals negativ
sein" beschreibt,...
Kommentare (0)
Melde dich an, um einen Kommentar zu schreiben.