Unit-Test Theorie und Praxis Stephan Seefeld, INGTES AG
Inhalt Was sind Unit-Test? NUnit für.net Demo Seite 2
Quellen Für diesen Vortrag verwendete Quellen: dotnet User Group Berlin Brandenburg http://www.dotnet-berlinbrandenburg.de/ Präsentationen von Michael Stumpf http://home.wtal.de/michael/mstumpf_nunit.ppt/ Development-Workshop mit Kent Beck NUnit-Dokumentation http://www.nunit.org/ Erfahrung aus der Praxis Seite 3
Unit-Test Deutsch: Modultest, Komponententest Vorgehen zur Verifikation der Korrektheit von Modulen (z. B. Klassen) einer Software. Seite 4
Unit-Test Möglichst jede Funktion mit Testfall abdecken. Testfälle werden als Code programmiert. Testfälle werden immer wieder ausgeführt (Regression). Vor einem Release müssen 100% der Tests erfolgreich sein. Seite 5
Positionierung Unit-Test White box Black box Unit-Test Regressionstest Performance-Test Integrationstest Seite 6
Jeder Programmierer schreibt Unit-Tests Ungetesteter Code läuft nicht. Konventionelle Entwicklertests Handeingabe im GUI Debuggen Testcode überall im Programm Unit-Tests Unterstützung durch Framework Tests sind reproduzierbar Seite 7
Entwickler als Tester Verbindet Code-Produktion mit Verantwortung für Code-Qualität. Schnelleres Feedback Weniger Angst vor dem Test Seite 8
und zudem... Weniger Mängel Gerechtfertigte Erhöhung der Selbstsicherheit Führt zu höherer Produktivität Bessere Programmarchitektur Besser änderbar Seite 9
Kosten Schulungsaufwand Werkzeuge Energie für Kulturwechsel Anstoss Chaos und Angst vor Änderungen Verhindern, dass das Rad zurück gedreht wird Zeit um Tests zu schreiben Seite 10
Grenzen von Unit-Tests Findet nicht jeden Programmfehler. Testet Module, aber findet keine Fehler bei der Integration, Performance-Probleme oder andere systemweiten Probleme. Nicht jeder denkbare Input kann geprüft werden. Unit-Tests mit anderen Tests kombinieren! Seite 11
Was kann ich mit Unit-Tests testen? Seite 12
Erwartetes Resultat testen Überprüfen, ob eine Methode das erwartete Resultat zurückgibt. Seite 13
Sonderfälle testen Jedes Objekt: Null Pointer Strings: Leerer String Collections: Leere Collection Genau ein Element Maximale Größe Duplikate Zahlen 0 Kleinste Zahl Etwas kleiner als die kleinste Zahl Größte Zahl Gerade grösser als grösste Zahl Summe Zahlen > MAX Suchen Nicht gefunden Ein Treffer Mehrere Treffer Seite 14
Einfluss auf die Architektur Abkopplung der zu testenden Objekte Entkoppeln von Units Parameter übergeben Interfaces Keine globalen Objekte mit Status (Singletons) Testbare Architekturen sind wartbarer! Entkopplung vereinfacht Änderungen Unit-Tests verringern das Risiko bei Änderungen Seite 15
Inhalt Was sind Unit-Test? NUnit für.net Demo Seite 16
NUnit Kompaktes Framework zum Unit-Testing Portiert von JUnit An.NET-Philosophie angepasst Unterstützt beliebige.net-sprachen OpenSource (C#) Aktuell: Version 2.2.8 Seite 17
Benutzeroberfläche von NUnit Seite 18
Wohin mit den Tests? In die zu testende Klasse? In die selbe Datei? In einer separaten Test-Assembly? In die selbe Assembly in eigene Klasse und Datei? Seite 19
Testaufbau Seite 20
Kennzeichnen von Tests [TestFixture] Kennzeichnet eine Test-Klasse. Klasse muss public sein und muss einen Standard- Konstruktor haben. [Test] Kennzeichnet eine Test-Methode. Methode muss parameterlos und ohne Rückgabewert sein. Seite 21
Weitere NUnit-Attribute [SetUp] Initialisierung, die vor jedem Testfall ausgeführt wird Darf nur einmal pro Testklasse existieren [TearDown] Aufräumen von Ressourcen nach jedem Test Darf nur einmal pro Testklasse existieren Seite 22
Noch mehr NUnit-Attribute... [ExpectedException] Verwendbar mit [Test] Erfordert Exception in der Test-Methode, sonst gilt der Testfall als fehlgeschlagen C# Syntax: [ExpectedException(typeof(myException))] [Ignore] Verwendbar mit [Test] Kennzeichnet eine Test-Methode als inaktiv C# Syntax: [Ignore( Grund für Ignorieren )] Seite 23
Die Klasse Assertion Aus Namespace NUnit.Framework Bietet statische Methoden zum Testen innerhalb einer mit [Test] gekennzeichneten Methode Seite 24
Methoden von Assertion AssertEquals(erwarteter_Wert, Resultat) Test schlägt fehl, wenn Parameter ungleich sind Resultatvergleich In vielen Varianten vorhanden Assert(Bedingung) Test schlägt fehl, wenn Parameter false ist Fail(Fehlermeldung) Test schlägt mit der angegebenen Begründung fehl Seite 25
Methoden von Assertion II AssertNotNull(object) Test schlägt Fehl, wenn Parameter null ist AssertNull(object) Test schlägt Fehl, wenn Parameter nicht null ist AssertSame(object, object) Test schlägt Fehl, wenn Parameter nicht das selbe Objekt referenzieren (Referenzvergleich) Seite 26
Inhalt Was sind Unit-Test? NUnit für.net Demo Seite 27
Implementieren von Tests Vorgehen Einbinden der Assembly nunit.framework.dll Verwenden des Namespace NUnit.Framework (using NUnit.Framework; in C#) Markieren der Testklassen und Methoden mit Attributen NUnit erkennt per.net-reflection die zu testenden Elemente innerhalb einer Assembly Seite 28
NUnit Nunit.framework Bietet Attribute und Hilfsfunktionen an. nunit-console.exe Produziert XML-Daten (Transformation mit XSLT) nunit-gui.exe Grafische Benutzeroberfläche für NUnit Praktisch: Ausgabe von Console.WriteLine(string) wird protokolliert Seite 29
Vorgehen Demo 1. Plattform: Visual-Studio 2003, NUnit 2.2.8 2. Form-Applikation erstellen 3. Klasse StringAnalyzer mit Methode static int ZaehleSterne erstellen 4. Klasse StringAnalyzerTest erstellen ZaehleSterne( *** ) 5. StringAnalyzerTest zur Testklasse machen 6. Testmethode ZaehleSterneTest erstellen Tests Normal, Split( * -1) 7. Test leerer String 8. Test Null -> ArgumentNullException() 9. Erweiterung: Andere Arten von Sternen z. B. * oder #. Sternenart als Property > Memory effekt > als Parameter 10. Klasse statt Static Setup / Teardown 11. String kommt von seriellem Stream - Interface Seite 30