Einige meiner Freunde hatten schon Mutmaßungen geäußert, das xUnit wohl das nächste Framework sein wird, welches ich mit "FizzBuzz" bearbeite. Keine Sorge, xUnit ist auch auf meiner Liste, aber heute soll zunächst einmal ein etwas weniger bekanntes Framework beäugelt werden: NSpec.
NSpec ist einer der ersten - wenn nicht sogar das erste explizite - BDD-Framework für .NET. Mittlerweile wird es auch nicht mehr aktiv betreut. "Schade", denkt man sich auf der einen Seite. Andererseits jedoch nicht sooo schlimm. Schließlich war der Autor mit dieser "finalen" Version offensichtlich zufrieden. Überdies ist die NSpec-Basis auch in andere Test-Frameworks eingeflossen - dazu aber später mehr. Bleibt auch noch anzumerken, dass man NSpec und MSpec nicht miteinander verwechseln sollte. Die Frameworks unterscheiden sich massiv, obwohl die Namensähnlichkeit das nicht vermuten lässt. Auch MSpec wird in meiner kleinen Serie sicherlich in der Zukunft noch seinen Platz finden. Doch nun zurück zu NSpec (N wie Nordpol) :-).
Bei NSpec dreht sich, wie nicht anders zu erwarten war, alles um Spezifikationen. Ich werde hier nicht näher auf die Gemeinsamkeiten oder Unterschiede zwischen TDD und BDD eingehen, werde auch nicht groß ausholen, wie und wieso BDD entstanden ist. Es sei nur kurz angerissen, dass bei BDD nicht das "testen" im Vordergrund steht, sondern die Spezifizierung des Verhaltens - Behavior Driven Design eben. Abgesehen von der Terminologie ergeben sich weitere Unterschiede, die auch am Beispiel von NSpec feststellbar sind. Genug Vorgeplänkel, auf geht's zum Test-Training mit dem FizzBuzz-Kata!
Der Ton macht die Musik - das Wort macht die Geschichte
Visual Studio öffnen, Projekt anlegen, Referenz hinzufügen, los geht's! Äähhh... wohl doch nicht... wie schreibt man eigentlich Spezifikationen im Code? Also Finger wieder weg von der Tastatur und überlegen, um was es eigentlich geht. Ok, es geht um FizzBuzz. FizzBuzz ist ein Spiel mit Spielregeln - das ist es im Endeffekt, worum es hier geht. So eine Spielregel ist recht einfach, denn es gibt zu einer bestimmten Spielsituation - sagen wir mal zu einem bestimmten Kontext - immer eine Regel, die man anwenden muss, damit man weiter im Spiel bleibt. Anders ausgedrückt ist bei einer Spielsituation zu prüfen, ob die Regel richtig angewendet wird - ob also die Erwartungen an das Spielverhalten erfüllt werden.
Aha - so ist das also. Hört sich vielleicht etwas abgedreht an, aber dieses kurze Repetitorium hilft beim Schreiben der ersten Spezifikation ungemein. Denn NSpec kennt zwei Attribute, namentlich [Context] und [Specification]. Mit der kleinen o.g. FizzBuzz-Geschichte macht das auch Sinn, wie man dann auch im Code sehen kann:
using NSpec.Framework; namespace FizzBuzzNSpec.Specs { [Context] public class when_a_number_is_a_multiple_of_three { [Specification] public void then_translation_should_return_fizz() { Specify.That(game.Translate(6)).ShouldEqual("Fizz"); } private readonly FizzBuzz game = new FizzBuzz(); } }
Anderes Framework, andere Sitten
Die Konsequenz dieser Verbalisierung und Strukturierung ist zunächst einmal eine verbesserte Lesbarkeit. Weiterhin fällt auf, dass es nicht mehr eine einzige "Testklasse" gibt, sondern 4 verschiedene Spezifikationsklassen. Für jede Spielregel eine. Das Stukturierungssystem ist zwar mit klassischen Test-Frameworks auch möglich, wird aber nicht so offensichtlich "verlangt" wie es das BDD-Test-Framework NSpec hier tut.
Den Code für die anderen Spielregeln spare ich mir - es sieht dem o.g. Beispiel sehr ähnlich :-). Hat man erst einmal das "sprechendere" schreiben der Tests bzw. Spezifikationen verinnerlicht, geht es mit NSpec auch zügig voran. Schade ist hier die fehlende Integration und Unterstützung für Visual Studio und die üblichen Code-Assistenten. Mir blieb also nichts anderes übrig, als in der Konsole meine Tests auszuführen. Das hat mich beim implementieren schon gebremst.
Bewertung
- Dauer
Naja, knapp 15 Minuten für FizzBuzz ist doch schon dreimal länger als mit NUnit. Die mangelnde Integration und die 4 Klassen machen schon etwas aus. - Größe
Statt wie bei den "Klassikern" 4 Methoden sind es nun 4 Klassen. Schon etwas mehr Code - hält sich aber noch "in Grenzen". - Tooling
Schlecht. Der Runner ist dabei - das war's. - Usability
Geht so. Die Assertions mitSpecifyreichen für die gröbsten Fälle aus. - Support
Die Entwicklung von NSpec ist eingestellt. Support damit auch. Zukunftssicherheit ist etwas anderes.
NSpec for a taste of BDD
NSpec - ein Vorreiter im .NET-Bereich was BDD angeht. Man merkt dem Framework deutlich an, dass es ein "erster Wurf" von der Adaption der BDD-Methodik ist. Nichtsdestotrotz ist as Framework schlank, stabil und gut anwendbar. Es zeigt schon in der Anwendung, wie das "System BDD" die Herangehensweise an die Spezifikation und Verifikation von Code ändert. Man beschäftigt sich automatisch mehr mit Kernaussagen und ist "gezwungen", sich deutlicher und expliziter in der Domänensprache zu artikulieren. NSpec kann diesen systematischen Aspekt transportieren, ist aber mittlerweile auf Grund der mangelnden Integration und des fehlenden Supports nicht mehr für "Real-World"-Projekte ernstzunehmen. Trotzdem hat mir der Ausflug mit NSpec Spaß gemacht. Da bekomme ich glatt Lust & Laune mir schon das nächste Framework anzuschauen. Stay tuned!