The Art of Unit Testing 01.02.2011 Marco Heimeshoff Heimeshoff@gmx.de
Übersicht Grundlagen des Unit Testing Test Driven Development Stubs & Mocks Behavior Driven Design The Art of Unit Testing
Definition A unit test is a piece of a code (usually a method) that invokes another piece of code and checks the correctness of some assumptions afterward. If the assumptions turn out to be wrong, the unit test has failed. A unit is a method or function [Kent Beck] Frei übersetzt: Ein Unittest ist ein Stück Software, das ein anderes Stück Software (eine Methode) aufruft und Annahmen zu seiner Funktionalität prüft. The Art of Unit Testing Grundlagen
Unittest Ein guter Unittest sei: Automatisiert und wiederholbar Einfach zu Implementieren Zukunftssicher Von jedem lesbar und ausführbar Auf Knopfdruck ausführbar Schnell The Art of Unit Testing Grundlagen
Integrationstest Der Begriff Integrationstest bezeichnet in der Softwareentwicklung eine aufeinander abgestimmte Reihe von Einzeltests, die dazu dienen, verschiedene voneinander abhängige Komponenten eines komplexen Systems im Zusammenspiel miteinander zu testen. [Wikipedia] The Art of Unit Testing Grundlagen
Unittest vs. Integrationstest The Art of Unit Testing Grundlagen
Unittest vs. Integrationstest The Art of Unit Testing Grundlagen
Unittest Frameworks Unittests werden als Code mit den Bibliotheken eines Frameworks geschrieben, und mit einem seperaten Unittestingtool ausgeführt. The Art of Unit Testing Grundlagen
Unittest Frameworks Nunit www.nunit.org MSTest ReSharper The Art of Unit Testing Grundlagen
Erste Schritte mit Unittest Testklasse und -methoden taggen [TestClass()] public partial class TestKlasse [TestInitialize()] public void MyTestInitialize() [TestCleanup()] public void MyTestCleanUp() [TestMethod()] [TestCategory("Daily")] public void MethodUnderTest_Scenario_ExpectedBehavior() Arrange, Act, Assert [TestMethod()] public void IsValidFileName_validFile_ReturnsTrue() { //arrange LogAnalyzer analyzer = new LogAnalyzer(); //act bool result = analyzer.isvalidlogfilename("whatever.slf"); //assert Assert.IsTrue(result, "filename should be valid!"); } The Art of Unit Testing Grundlagen
Erste Schritte mit Unittest Die Assert-Klasse hat statische Methode und liegt im Namespace Microsoft.VisualStudio.TestTools.UnitTesting. Sie dient zu Überprüfung von Annahmen. Assert Arrange, Act, Assert [TestMethod()] public void IsValidFileName_validFile_ReturnsTrue() { //arrange LogAnalyzer analyzer = new LogAnalyzer(); //act bool result = analyzer.isvalidlogfilename("whatever.slf"); //assert Assert.IsTrue(result, "filename should be valid!"); Assert.AreEqual(3, 3, "Zahlen stimmen nicht überein"); Assert.AreSame((int)3,(int)3, "Zahlen stimmen nicht überein"); Assert.IsNotNull(result, "Kein Ergebnis gefunden"); } The Art of Unit Testing Grundlagen
Test Driven Development Das Mantra der Testgetriebenen Entwicklung Red Green Refactor Einzelschritte Erstelle einen Test Compiliere ihn und stelle sicher, dass es fehlschlägt) Schreibe das Interface Compiliere erneut Starte den Test und stelle sicher, dass er rot wird Implementiere Programmcode Compiliere/Starte den Test und stelle sicher, dass er grün wird Refaktoriere deinen Code, um ihn wartbar und lesbar zu halten The Art of Unit Testing Test Driven Development
Test Driven Development Traditionell Test Driven The Art of Unit Testing Test Driven Development
Stubs & Mocks Ein Stub ist ein kontrollierbarer Ersatz für eine existierende Abhängigkeit im System. Durch benutzen eines Stubs kann man das System testen, ohne sich im die Abhängigkeit kümmern zu müssen [Roy Osherove] The Art of Unit Testing Stubs & Mocks
Stubs Zustandsbasierter Test The Art of Unit Testing Stubs & Mocks
Stubs Zustandsbasierter Test Wenn ein Stub benutzt wird, wird das Assert gegen die Klasse unter Test angewendet. Das Stub stellt sicher, dass der Test sauber abläuft. The Art of Unit Testing Stubs & Mocks
Mocks Ein Mockobjekt ist ein Fakeobjekt im System, das entscheidet ob ein Test erfolgreich ist, indem es die Interaktionen des zu testenden Objektes verifiziert. [Roy Osherove] The Art of Unit Testing Stubs & Mocks
Mocks Interaktionstest Die Klasse unter Test kommuniziert mit dem Mock, und alle Kommunikation wird im Mock gespeichert. Der Test benutzt das Mock, um zu verifizieren das der Test erfolgreich verlief. The Art of Unit Testing Stubs & Mocks
Mocks Interaktionstest public class MockService : IWebService { public string LastError; } public void LogError(string message) { LastError = message; } [TestMethod] public void Analyze_TooShortFileName_CallsWebService() { MockService mockservice = new MockService(); LogAnalyzer log = new LogAnalyzer(mockService); string tooshortfilename = "abc.ext"; log.analyze(tooshortfilename); Assert.AreEqual("Filename too short:abc.ext", mockservice.lasterror); } public class LogAnalyzer { private IWebService service } public LogAnalyzer(IWebService service) { this.service = service; } public void Analyze(string filename) { if (filename.length < 8) { service.logerror("filename too short:" + filename); } } The Art of Unit Testing Stubs & Mocks
Stubs & Mocks Isolationframeworks Ein Isolationsframework ist ein Satz programmierbarer APIs, der das Erstellen von Stubs und Mocks vereinfacht. Es erspart dem Programmierer repetetiven Code zu schreiben um Objektinteraktionen zu testen oder zu Simulieren. [Roy Osherove] The Art of Unit Testing Stubs & Mocks
Stubs & Mocks Isolationframeworks Verbreitung 2009 The Art of Unit Testing Stubs & Mocks
Stubs & Mocks Moq Ein relativ neues Framework Erfordert.Net 3.5 durch Einsatz von Lamdas Einfache Installation (Moq.dll als Referenz) Geringere Lernkurve Im Gegenzatz zu Rhino erlaubt es fake protected Methods The Art of Unit Testing Stubs & Mocks
Stubs & Mocks Moq var mock = new Mock<IFoo>(); mock.setup(foo => foo.dosomething("ping")).returns(true); // ref arguments var instance = new Bar(); // Only matches if the ref argument to the invocation is the same instance mock.setup(foo => foo.submit(ref instance)).returns(true); // Stub: start "tracking" sets/gets to this property mock.setupproperty(f => f.name); // Stub: alternatively, provide a default value for the stubbed property mock.setupproperty(f => f.name, "foo"); // Now you can do: IFoo foo = mock.object; // Initial value was stored Assert.Equal("foo", foo.name); // New value set which changes the initial value foo.name = "bar"; Assert.Equal("bar", foo.name); http://code.google.com/p/moq/wiki/quickstart The Art of Unit Testing Stubs & Mocks
Behavior Driven Design Die Stützpfeiler guter Tests Vertrauenswürdigkeit Wartbarkeit Lesbarkeit The Art of Unit Testing Behavior Driven Design
Behavior Driven Design BDD ist eine agile Softwareentwicklungsstrategie, die das Zusammenspiel von Entwicklern, QA und nichttechnischen- oder Businesspartnern durch eine gemeinsame Sprache ermöglicht. The Art of Unit Testing Behavior Driven Design
Behavior Driven Design Scenario: Logging in with correct credentials Given a user with username "bdduser" and password "bddpassword" And is an active user in the system When a visitor logs in with username "bdduser" and password "bddpassword" Then the visitor is logged in as a "User" Scenario: Logging in with incorrect credentials Given no user exists with the username "bddbaduser" When a visitor logs in with username "bddbaduser" and password "bddbadpassword" Then the visitor is not logged in The Art of Unit Testing Behavior Driven Design
Behavior Driven Design The Art of Unit Testing Behavior Driven Design
Behavior Driven Design StoryQ The Art of Unit Testing Behavior Driven Design
Fazit Unittest erhöhen die Qualität und Akzeptanz Schnell durchführbar Isoliert Benötigen keine externe Konfiguration Geben ein konsistentes Pass/Fail Ergebnis über Features aus The Art of Unit Testing
Offene Fragen Inversion of Control bei Stubs Andere Mockframeworks Automatisierte Tests während des Builds Wie überzeuge ich mein Team Top Down or Bottom up / Champions&Blockers Wie teste ich Legacy Code The Art of Unit Testing
The Art of Unit Testing Vielen Dank