Unit Tests sind wichtig!
Der Nutzen automatisierter Tests wird inzwischen zwar nicht mehr in Frage gestellt. Doch immer noch treffe ich auf Entwickler, denen es schwer fällt, regelmäßig Unit Tests zu schreiben. Im folgenden stelle ich 4 Tools vor, mit denen das Testen leichter von der Hand geht. Das hilft Ihnen vielleicht dabei, zu einem leidenschaftlichen Tester zu werden.
NCrunch
NCrunch ist aktuell mein Lieblings-Plugin für Visual Studio! Es erhöht meine Produktivität, da ich die Tests nicht mehr manuell starten muss.
- Test laufen automatisiert (Continuous Testing)
Mit NCrunch werden Ihre Unit Tests kontinuierlich ausgeführt, so dass Sie nach jeder Codeänderung sofort erkennen können, ob noch alles in Ordnung ist. NCrunch zeigt dazu in der Fußleiste von Visual Studio ein Symbol an, mit dem Sie sofort erkennen können, ob möglicherweise Tests fehlgeschlagen sind. Das Arbeiten in Visual Studio bleibt trotzdem flüssig, da NCrunch sehr ressourcenschonend arbeitet. Sie werden durch NCrunch produktiver, da die Tests nun vollautomatisch ausgeführt werden. - Code Coverage
Durch einen farbigen Punkt links neben jeder Codezeile zeigt NCrunch an, ob diese Zeile durch einen der Tests ausgeführt wurde. So erkennen Sie in Ihrem Code sofort Zeilen, die nicht durch einen Test abgedeckt sind und können dazu Tests ergänzen.
In der folgenden Abbildung sehen Sie das ReSharper und das NCrunch Symbol in trauter Zweisamkeit nebeneinander. ReSharpers grüner Haken sagt: keine Fehler in der Solution. NCrunchs „N“ sagt, alle Tests erfolgreich durchlaufen, NCrunch hat gerade nichts zu tun.
In der folgenden Abbildung sehen Sie Codezeilen, die nicht durch einen Test abgedeckt sind (schwarzer Punkt), sowie solche, die durch einen erfolgreichen Unit Test abgedeckt sind (grüner Punkt). Schlägt ein Test fehl, werden rote Punkte angezeigt.
Zu weiteren Informationen und einer 30 Tage Testversion.
ReSharper
Mein Langzeit-Favorit bei den Visual Studio Plugins ist natürlich JetBrains ReSharper. Die Refactoring Werkzeuge sind extrem leistungsfähig. Ferner bietet ReSharper zahlreiche Navigationswerkzeuge, um schnell an die gewünschte Stelle im Code zu springen.
- Testrunner
Der Testrunner von ReSharper unterstützt NUnit, XUnit und MSTest. Für JavaScript werden QUnit und Jasmine unterstützt. Bei fehlgeschlagenen Tests wird Ihnen ein Stacktrace angezeigt, in dem Sie mittels Links zu den jeweiligen Codestellen navigieren können. Sehr komfortabel. - Find & Replace mit Custom Patterns
Mit den passenden Custom Patterns können Sie bspw. die alte Assert.AreEqual Syntax mit einem einzigen Tastendruck in die leistungsfähigere Assert.That Syntax umwandeln. Die folgende Abbildung zeigt, wie das Custom Pattern zu definieren ist.
Die Platzhalter $expected$ und $actual$ werden von ReSharper automatisch durch die jeweiligen Parameter gefüllt. So können Sie ein Muster definieren, nach dem eine Ersetzung im Quelltext vorgenommen werden soll. Durch die Einstellung „Show as warning“ werden Assert.AreEqual Aufrufe im Quelltext als Warnung angezeigt. Mit der Tastenkombination Alt+Enter wandeln Sie die Schreibweise dann ganz einfach um. Und selbstverständlich können Sie diese Muster für ein Suchen & Ersetzen in einer Datei, einem Projekt oder sogar der gesamten Solution anwenden. Ein weiteres typisches Anwendungsgebiet sind Anpassungen an eine geänderte API Syntax. Mit dem passenden Muster können Sie die Aufrufe einer älteren API Version auf eine neue Version umstellen.
Zu weiteren Informationen und einer 30 Tage Testversion.
NUnit
Ich nutze NUnit für automatisierte Tests. NUnit bietet mir
- datengetriebene Tests und
- eine Visual Studio Testrunner Integration.
Häufig steht man bei automatisierten Tests vor der Herausforderung, viele Tests zu schreiben, die sehr ähnlich sind. NUnit bietet mit den datengetriebenen Tests die Möglichkeit, die Eingaben und den erwarteten Wert über Attribute zu definieren:
[Test] [TestCase("A;B", new[] { "A", "B" })] [TestCase("\"A\";\"B\"", new[] { "A", "B" })] [TestCase("\"A\";B", new[] { "A", "B" })] [TestCase("\"A;B\"", new[] { "A;B" })] public void Alle_Beispiele(string input, string[] expeted_result) { Console.WriteLine(input); var result = sut.Parse(input); Assert.That(result.First(), Is.EqualTo(expeted_result)); }
In diesem Beispiel aus einem CSV Parser möchte ich für viele mögliche Eingabestrings prüfen, ob dieser jeweils in die erwartete Ausgabe zerlegt wird. Dazu verwende ich das TestCase Attribut. Alle Objekte des Attributs werden an die Parameter der Testmethode übergeben. So definiert der obige Test gleich vier Testfälle.
Um die NUnit Tests innerhalb von Visual Studio auszuführen, verwende ich üblicherweise den ReSharper Testrunner. Verfügen Sie über keine ReSharper Lizenz und möchten Sie NUnit dennoch einsetzen, installieren Sie über NuGet einfach das Paket NUnitTestAdapter. Anschließend stehen die NUnit Tests im Visual Studio Test Explorer zur Verfügung.
Equalidator
Vermutlich haben Sie bei Tests schon vor der Herausforderung gestanden, zwei Datenstrukturen miteinander zu vergleichen. Sehen Sie sich den folgenden Test an:
[Test] public void Zwei_Koordinten_vergleichen() { var p1 = new Koordinate(1, 2); var p2 = new Koordinate(1, 2); Assert.That(p1, Is.EqualTo(p2)); }
Zwei Koordinaten werden mit den gleichen Werten instanziert. Sind die beiden Objekte gleich? Dazu müssen Sie wissen, wie die Klasse Koordinate definiert ist:
public class Koordinate { public Koordinate(int x, int y) { X = x; Y = y; } public int X { get; private set; } public int Y { get; private set; } }
In diesem Fall sind die beiden Objekte nicht gleich, da es sich um eine class handelt. Bei struct wären sie gleich. An manchen Stellen im Code könnte die Lösung darin bestehen, die class zu einem struct zu ändern. Doch dies ist sicher nicht die generelle Lösung für das Problem. Auch das Implementieren der Equals und GetHashCode Methoden stellt nicht immer die Lösung dar, allemal, wenn diese nur für die Tests benötigt werden.
Die Lösung lautet Equalidator. Dabei handelt es sich um ein Open Source Projekt meines Kollegen Ralf Westphal. Es steht als NuGet Paket zur Verfügung und ist schnell in ein Testprojekt eingebunden. Mit Equalidator sieht der Vergleich der beiden Koordinaten wie folgt aus:
Equalidator.AreEqual(p1, p2);
Und dieses Mal ist der Test grün, egal ob als class oder struct implementiert. Equalidator vergleicht die beiden Objekte Eigenschaft für Eigenschaft. Sind alle Werte gleich, gelten die Objekte als gleich. Und Equalidator geht noch einen Schritt weiter und vergleicht auch Listen, Arrays und andere Aufzählungen Element für Element. Eine echte Erleichterung für automatisierte Tests.
Was sind Ihre wichtigsten Tools? Schreiben Sie einen Kommentar.
Oh ja, Continuous Testing ist ein sehr nützlicher Ansatz, nicht nur um Legacy Code umzustrukturieren. Wenn jetzt noch das automatisierte Erstellen von Unit Tests in VS zuverlässig funktionieren würde (für NUnit und MSTest), könnte man auch noch den letzten Kritiker und Projektleiter überzeugen.
Da ich sowieso eine ReSharper Ultimate Lizenz habe, nutze ich zur Darstellung der Testabdeckung und des kontinuierlichen Testens das Tool dotCover. In der neuesten Version hat es nämlich auch ein Continuous Testing Session Explorer, mit dem die Tests automatisch entweder nach dem Speichern einer Quellcodedatei oder nach dem Erstellen gestartet werden. Etwas vergleichbares kannte ich bisher nur von NetBeans. Es ist schön, so etwas auch für das Visual Studio zu haben.
Den Equalidator von Ralf habe ich auch ausprobiert (sobald er das getwittert hatte :)) und bin sehr erstaunt und zufrieden damit. Und erstaunt, warum noch niemand vorher auf den Gedanken gekommen ist.
Den Continuous Test Runner vom ReSharper Ultimate kann ich auch empfehlen. Dank dotCover werden auch nur die Tests neu durchlaufen, die den nach dem letzten Run gänderten Code abdecken.
I not that much of a online reader to be honest but your sites really nice, keep it up! I’ll go ahead and bookmark your website to come back later on. Many thanks
I together with my guys have already been going through the great techniques located on your site and so all of a sudden developed an awful suspicion I never expressed respect to you for those tips. The young boys became consequently very interested to see all of them and have very much been loving these things. Appreciate your actually being simply accommodating and for deciding upon this kind of useful tips most people are really desirous to understand about. Our sincere regret for not saying thanks to you earlier.