Follow my new blog

Freitag, 11. September 2009

Code Kata statt Thai Chi vor dem Frühstück [endlich-clean.net]

Statt einer Zeitung lese ich am Morgen vor dem Frühstück gern meine RSS-Feeds. Heute fand ich darin einen Bericht vom ersten Coding Dojo in München. Der hat mich motiviert, die FizzBuzz Kata auch gleich mal zu machen.

Welch erweckende Tätigkeit am Morgen! Statt sich beim Thai Chi im Park die Füße im Gras nass zu machen, lieber im Bett die geistigen Energien in Fluss bringen :-) Eine kleine Kata vor dem Frühstück macht frisch und kregel. FizzBuzz ist nicht schwierig vom Problem her, bietet dem “Testmuskel” aber genügend Widerstand, um einen Übungseffekt zu erzielen.

Mir ist heute dabei z.B. diese kleine Erkenntnis gekommen: Was mache ich eigentlich, ich weiß, das mein Code für Einzelfälle korrekt ist, aber noch prüfen möchte, ob er auch im allgemeinen Fall oder größeren Umfang läuft? Wie sieht sozusagen mein “Induktionsbeweis” aus?

Beispiel FizzBuzz Kata: Ich hatte geprüft, dass meine Klasse FizzBuzzGenerator für 1, 2, 3, 5, 15 den erwarteten Output liefert: “1”, “2”, “Fizz”, “Buzz”, “FizzBuzz”. Der API ist ganz einfach:

var fbg = new FizzBuzzGenerator();

Assert.AreEqual("1", fbg.Next());

Zum Abschluss wollte ich dann noch einen Test mit einer längeren Folge von Zahlen durchlaufen lassen. Die bisherigen Tests hatten eher separat die Generierung von Zahlen und die Prüfung auf Fizz usw. geprüft. Die längere Zahlenfolge war für mich eine Art Integrationstest. Hier der Code:

[Test]

public void Integrationstest()

{

    var sut = new FizzBuzzGenerator();

    var folge = new List<string>() { "1", "2", };

 

    while(folge.Count > 0)

    {

        Assert.AreEqual(folge[0], sut.Next());

        folge.RemoveAt(0);

    }

}

Dabei bin ich über zwei Fragen gestolpert: Wie kann ich bei so einem Test dem Muster red-green-refactor folgen, wenn ich doch schon die Erwartung habe, dass mein Code korrekt ist? Und: Wie kann auch sicher sein, dass mein Testcode korrekt ist?

Zunächst habe ich diese Fragen beiseite geschoben und mir einfach gesagt, dass das hier ein triviales Beispiel sei und es schon einfach laufen würde.

Doch dann haben sich die Fragen von selbst beantwortet.

Die Antworten kamen aus der Folge des erwarteten Output, die zunächst so aussah: “1”, “2”, “Fizz”, “4”, “Buzz”, “6”, “7”, “8”, “Fizz”, “10”, “11”, “12”, “13”, “14”, “FizzBuzz”, …

Wer sieht, worin die Antwort besteht?

Die Antwort lautet: Wenn du eigentlich sicher bist, dass die zu testende Funktionalität korrekt ist, dann baue in die Erwartungen des Tests Fehler ein, um ihn im ersten Anlauf rot zu machen.

Das hatte ich unwillentlich mit meiner Output-Folge getan, weil ich 6,  10 und 12 nicht als “Buzz” bzw. “Fizz” eingetragen hatte. Das doppelt positive Ergebnis des ersten Testlaufs war daher:

  1. Der Test schlug fehl, weil er auf eine inkorrekte Erwartung gelaufen war. Das bedeutete im Umkehrschluss, dass der Testalgorithmus korrekt war, denn sonst wäre er gar nicht erst zu dieser Erwartung gekommen.
  2. Die inkorrekte Erwartung wurde erkannt, so dass auch das System Under Test für diesen bisher nicht getesteten Fall korrekt war.

Nach Korrektur der fehlerhaften Erwartungen lief dann alles glatt und ich war zuversichtlich, dass nun das integrierte Ganze wirklich fehlerfrei war.

So hat eine kleine Code Kata meinen Testmuskel noch vor dem Frühstück sehr angenehm gestärkt und für den Tag fit gemacht. Eine empfehlenswerte Praktik für alle, die für den Frühsport lieber im Haus bleiben wollen ;-)

1 Kommentar:

Peter Gfader hat gesagt…

Hallo Ralf.
Roy Osherove empfiehlt bei Code reviews von Tests, alle Tests zu brechen und wirklich zu schauen ob die Tests nicht IMMER grün sind.
D.h. baue Fehler ein und schaue ob Tests wirklich brechen (rot werden)

Code reviews für Tests --> awesome :-)