Technische Artikel

Einfache Test Driven Development Übung

Einfache Test Driven Development Übung

Die Qualität deines geschriebenen Codes ist von entscheidender Bedeutung. Sie beeinflusst nicht nur die Funktionalität deiner Anwendung, sondern auch deren Wartbarkeit und Skalierbarkeit. 

Deshalb ist es unerlässlich, die besten Praktiken zu nutzen, um diesen Standard zu erreichen und aufrechtzuerhalten.

Mit Test Driven Development (TDD) kannst du sicherstellen, dass dein entwickelter Code nicht nur funktioniert, sondern auch den höchsten Qualitätsstandards entspricht. Damit du TDD einfach in deinen Arbeitsalltag integrieren kannst, ist eine regelmäßige Übung unerlässlich.

Die FizzBuzz Kata eignet sich hervorragend dafür, TDD zu verstehen, zu verinnerlichen und zu üben.

Bevor du startest

  • Dieser Artikel setzt das Grundverständnis von Test Driven Development voraus. Sollte dir TDD noch unbekannt sein oder du dein Gedächtnis auffrischen wollen, lies dir vorab den Artikel Test Driven Development einfach erklärt durch.
  • Die Übung kannst du in jeder Programmiersprache absolvieren. Für diesen Artikel wurde Go als Sprache ausgewählt. Schau dir den Artikel Erste Schritte mit Go an, wenn du mehr zu Go erfahren willst.
  • Du benötigst
    • ein lokales Setup für deine Sprache
    • ein zugehöriges Testframework
    • etwas Zeit für die Übung

FizzBuzz in TDD-Schritten

Die Aufgabenstellung der FizzBuzz Kata ist ganz einfach:

  • Du zählst von 1 bis zu einer bestimmten Zahl durch und gibst diese zurück.
  • Wenn deine Zahl durch 3 teilbar ist, gibst du statt der Zahl das Wort „Fizz“ zurück.
  • Wenn deine Zahl durch 5 teilbar ist, gibst du das Wort „Buzz“ zurück.
  • Und wenn die Zahl sowohl durch 3 und 5 teilbar ist, gibst du das Wort „FizzBuzz“ zurück.

Diese Aufgabenstellung gilt es jetzt mit Hilfe von TDD zu lösen.

TDD Zyklus

Der TDD Zyklus sieht wie folgt aus:

  • Schritt 1: Du erstellst einen Test der fehlschlägt –> Rote Phase
  • Schritt 2: Du schreibst den zugehörigen Code bis der Test grün ist –> Grüne Phase
  • Schritt 3: Du refaktorierst deine Tests und deinen Code –> Blaue Phase

–> Der TDD-Zyklus beginnt von vorne

Als Unterstützung kannst du auch gerne das TDD Prisma verwenden, dass von Michael Kutz entworfen wurde. Du kannst es ausdrucken, kleben und anwenden.

⑤ Glue basesto sides① Cut along thedashed lines③ Fold sidesinwardREDGREENREFACTOR① Write a failing testall tests pass③ Optimize the codeall tests pass there is a failing testthere is a failing test② Make the tests passall tests passall tests pass② Fold rightbase inward② Fold leftbase inward④ Glue sidestogether© Michael Kutz 2023michael-kutz.deTest DrivenDevelopmentPrism

Setup vorbereiten

Bereite als erstes dein Setup vor, indem du ein neues Projekt anlegst.

Solltest du Go für diese Übung nutzen wollen, findest du unter Erste Schritte mit Go eine Anleitung für die Installation von Go und das Initialisieren eines neuen Projektes.

Als nächstes benötigst du eine Datei, in der du deine Tests schreiben kannst. Lege hierfür im Hauptverzeichnis deines Projektes eine Datei mit dem Namen fizzBuzz_test.go an.

Tests schreiben

Bevor du mit dem Schreiben der Tests startest, verinnerliche dir folgende Vorgehensweise:

Lasse nach jeder Änderung alle deine Tests durchlaufen.

So kannst du sicherstellen, dass deine Änderungen die Funktionalität nicht beeinträchtigt haben.

Schreibe deinen ersten Test

Rote Phase

Nun kannst du mit dem ersten Test beginnen. Am einfachsten ist es, wenn du einen simplen Fall auswählst, wie etwa:

Der Test erwartet, dass die Zeichenkette 1 zurückgegeben wird.

Etwa so:

Die FizzBuzz() Funktion wurde noch nicht implementiert, weshalb der Compiler die Fehlermeldung „undeclared name: FizzBuzz“ ausgibt.

Um dies zu beheben, kannst du nun eine Funktion FizzBuzz() deklarieren. Diese gibt einen leeren String als Rückgabewert aus.

Schreibe deine FizzBuzz() Funktion in die main.go Datei:

Mit dieser Implementierung ist der Compiler zufrieden. Du kannst jetzt deinen Test durchlaufen lassen.

Der Test erwartet einen String Wert 1, erhält jedoch einen leeren String über deine FizzBuzz() Funktion. Somit schlägt der Test fehl.

Hier beginnt der Wechsel von der roten in die grüne Phase.

Grüne Phase

Du schaust dir deine Implementierung an und überlegst, was du tun kannst, damit dein Test grün wird.

In diesem Fall ist es ganz einfach: statt eines leeren Strings, gibst du die Zeichenkette 1 zurück.

Dein Test ist grün und du kannst in die blaue Phase wechseln.

Blaue Phase

In der blauen Phase überlegst du dir, ob du etwas refaktorisieren kannst.

Da es hier weder im Test noch im Code etwas zu refaktorisieren gibt, kannst du mit dem nächsten Test weitermachen.

Schreibe deinen zweiten Test

Rote Phase

Der Test erwartet, dass die Zeichenkette 2 zurückgegeben wird.

Etwa so:

Du lässt deinen Test durchlaufen und er schlägt fehl. Da du in der FizzBuzz() Funktion die Zeichenkette 1 zurückgibst, kann dein Test nicht erfolgreich sein.

Grüne Phase

Zeit, deine FizzBuzz() Funktion anzupassen.

Du kannst zum Beispiel einen Parameter in die Funktion geben, der als Zeichenkette ausgegeben wird.

Das bedeutet allerdings, dass du deine Tests anpassen musst. Die FizzBuzz() Funktion erwartet nun einen Parameter.

Lass die Tests durchlaufen.

Die Tests sind grün und du kannst in die blaue Phase wechseln

Blaue Phase

Stell dir die Frage, ob es hier etwas zu refaktorisieren gibt.

Die Tests können vereinfacht werden. Statt die Variablen actual und expect zu deklarieren, kannst du die Werte direkt übergeben.

Das Naming deiner Tests kann angepasst werden. So wird deutlicher, was im Test passieren soll.

Schreibe deinen dritten Test

Versuche den TDD-Zyklus alleine durchzugehen, bevor du dir die Lösung anschaust.

Rote Phase

Der Test erwartet, dass die Zahl 3 die Zeichenkette „Fizz“ zurückgibt.

Der Test schlägt fehl, da die Zeichenkette 3 zurückgegeben wird.

Grüne Phase

Du kannst im Code eine Bedingung einfügen, damit bei der Zahl 3 die Zeichenkette „Fizz“ zurückgegeben wird.

Blaue Phase

Gibt es etwas zu refaktorisieren? Wenn nicht, starte mit dem vierten Test.

Schreibe deinen vierten Test

Versuche auch hier den TDD-Zyklus alleine durchzugehen, bevor du dir die Lösung anschaust.

Rote Phase

Der Test erwartet, dass die Zahl 4 die Zeichenkette „4“ zurückgibt.

Dieser Test läuft korrekt durch, da die Implementierung des Codes bereits korrekt ist.

Grüne Phase

Es sind keine Anpassungen notwendig, da der Code schon korrekt geschrieben ist.

Blaue Phase

Tatsächlich kannst du jetzt deine Tests refaktorisieren.

Du kannst etwa die Testfälle 1, 2, und 4 verbinden. Hierfür schreibst du einen neuen Test, der alle Fälle zusammenfasst. Wenn der Test erfolgreich durchläuft, kannst du die duplizierten Tests entfernen.

Etwa so:

Schreibe deinen fünften Test

Rote Phase

Der Test erwartet, dass die Zahl 5 die Zeichenkette „Buzz“ zurückgibt.

Grüne Phase

Für die Anpassung im Code benötigst du eine weitere Bedingung.

Blaue Phase

Gibt es etwas zu refaktorisieren?

Schreibe deinen sechsten Test

Rote Phase

Der Test erwartet, dass die Zahl 6 die Zeichenkette „Fizz“ zurückgibt. Denn 6 ist durch 3 teilbar.

Grüne Phase

Deine Bedingung im Code muss erweitert werden. Sie sieht nun so aus:

Blaue Phase

Tatsächlich kannst du deinen Test refaktorisieren, in dem du die beiden „Fizz“ Tests verbindest.

Denk daran, schreibe zuerst einen neuen Test der beide Erwartungen enthält. Sobald der Test erfolgreich durchgelaufen ist, kannst du die Duplikate entfernen.

Schreibe deinen siebten Test

Rote Phase

Du kannst jetzt einen Sprung machen, denn die Zahlen 7 und 8 geben schon das gewünschte Ergebnis zurück.

Der Test erwartet, dass die Zahl 9 die Zeichenkette „Fizz“ zurückgibt.

Der Test hierzu:

Grüne Phase

Um diesen Test erfolgreich durchlaufen zu lassen, musst du deine Bedingung erweitern.

Blaue Phase

Refaktorisiere deine Tests indem du einen neuen Testfall für die Zahlen 3, 6 und 9 schreibst. Sobald der Test erfolgreich durchgelaufen ist, kannst du die Duplikate entfernen

In der FizzBuzz() Funktion kannst du die if Bedingung für den Rückgabewert „Fizz“ anpassen. Wenn die Zahl durch 3 teilbar ist, wird „Fizz“ ausgegeben. Hierfür kannst du den Modulus Operator verwenden.

Wenn die Zahl durch 3 teilbar ist und kein Rest übrig bleibt, wird „Fizz“ ausgegeben.

Lass deine Tests durchlaufen und du wirst sehen, dass die Änderungen im Code erfolgreich waren.

Schreibe deinen achten Test

Rote Phase

Der Test erwartet, dass die Zahl 10 die Zeichenkette „Buzz“ zurückgibt.

Grüne Phase

Eine Erweiterung der Bedingung lässt den Test grün werden.

Blaue Phase

Hier kann sowohl die Funktion wie auch der Test refaktorisiert werden:

In der Bedingung kannst du den Modulus Operator für das Teilen durch 5 anwenden:

Schreibe deinen neunten Test

Rote Phase

Der Test erwartet, dass die Zahl 15 die Zeichenkette „FizzBuzz“ zurückgibt.

Da 15 durch 5 teilbar ist, wird allerdings „Buzz“ ausgegeben.

Grüne Phase

Erweitere deine Bedingung für die Zahl 15.

Blaue Phase

Findest du etwas zum Refaktorisieren?

Schreibe deinen zehnten Test

Rote Phase

Der Test erwartet, dass die Zahl 30 die Zeichenkette „FizzBuzz“ zurückgibt.

Grüne Phase

Erweitere deine Bedingung, damit der Test grün wird.

Blaue Phase

Refaktorisiere deinen Test. Schreibe einen neuen Test, um die Fälle für 15 und 30 zusammenzubringen. Entferne danach die Duplikate.

Refaktorisiere deinen Code. Nutze den Modulus Operator für das Teilen durch 15.

Nächste Schritte

Da du durch deine Tests die Funktionalität deines Code nun komplett abdeckst, kannst du nun größere Refaktorisierungs-Schritte durchführen:

  • Kannst du „return“ nur einmal aufrufen?
  • Wie lassen sich die Bedingungen zusammenfügen?

Eine Möglichkeit den Code zu refaktorisieren, wäre diese:

Nach der Änderung lässt du deine Tests durchlaufen. Wenn deine Tests weiterhin grün sind, hast du das Refactoring erfolgreich durchgeführt.

Fazit

Mit dieser Übung hast du eine praktische Anwendung von TDD erhalten.

Möglicherweise fragst du dich, wie sinnvoll diese Vorgehensweise im Arbeitsalltag ist, insbesondere wenn Zeitdruck herrscht. Immerhin hättest du einige der Schritte überspringen und direkt mit der Implementierung des Modulus Operators beginnen können.

Tatsächlich haben diese kleinen Schritte des TDD einen bedeutenden Effekt. Indem du einen Fall nach dem anderen bearbeitest, zwischendurch immer wieder deine Tests laufen lässt und regelmäßig refaktorisierst, entwickelst du einen hohen Qualitätsstandard.

Zudem wirst du feststellen, dass eine schnelle und unüberlegte Vorgehensweise zu Fehlern führen kann. In einer Übung wie der FizzBuzz Kata können Baby-Schritte zu Unterforderung führen. Doch in komplexen Situationen kann dir diese Vorgehensweise extrem helfen. Dafür musst du sie verinnerlichen.

Mit Übungen wie der FizzBuzz Kata kannst du dir diese Herangehensweise aneignen, ohne viel darüber nachzudenken. Je besser du sie verinnerlicht hast, desto leichter fällt dir die Anwendung in komplexen Bereichen.

Deshalb ermutige ich dich, dir diese Vorgehensweise anzueignen, zu üben und in umfangreichen Projekten zu nutzen.

Weitere Katas

Neben der FizzBuzz-Kata gibt es viele weitere Übungen, die sich optimal für Test Driven Development eignen.

Wirf gerne einen Blick auf die folgenden beiden Katas:

Des Weiteren findest du hier eine Zusammenstellung verschiedener Katas mit unterschiedlichen Schwierigkeitsgraden.

In meinem Artikel Refactoring Übung: die Gilded Rose Kata, kannst du deine TDD-Kenntnisse direkt anwenden.

Ich wünsche dir viel Spaß und Erfolg beim Umsetzen von Test Driven Development.

Quelle Hintergrund des Titelbilds: kostenlose Hintergrundfotos von .pngtree.com

Was dir auch gefallen könnte...

WordPress Cookie Hinweis von Real Cookie Banner