Inhaltsverzeichnis

Impressum

Vorwort zur zweiten Auflage

Vorwort zur ersten Auflage

Einleitung

Teil I: Erste Schritte

Kapitel 1: Die Grundlagen des Unit Testings

1.1 Unit Testing – Schritt für Schritt definiert

1.1.1 Die Bedeutung guter Unit Tests​

1.1.2 Wir alle haben schon Unit Tests geschrieben (irgendwie)

1.2 Eigenschaften eines »guten« Unit Test​​s

1.3 Integrationstests​

1.3.1 Nachteile von nicht automatisierten Integrationstests​ im Vergleich zu automatisierten Unit Tests

1.4 Was Unit Tests »gut« macht

1.5 Ein einfaches Unit-Test-Beispiel

1.6 Testgetriebene Entwicklung​

1.7 Die drei Schlüsselqualifikationen für erfolgreiches TDD

1.8 Zusammenfassung

Kapitel 2: Ein erster Unit Test

2.1 Frameworks für das Unit Testing

2.1.1 Was Unit-Testing-Frameworks bieten

2.1.2 Die xUnit-Frameworks

2.2 Das LogAn-Projekt​ wird vorgestellt

2.3 Die ersten Schritte mit NUnit

2.3.1 Die Installation von NUni​t

2.3.2 Das Laden der Projektmappe

2.3.3 Die Verwendung der NUnit​-Attribute in Ihrem Code

2.4 Sie schreiben Ihren ersten Test

2.4.1 Die Klasse Assert​

2.4.2 Sie führen Ihren ersten Test mit NUnit aus

2.4.3 Sie fügen positive Tests hinzu

2.4.4 Von Rot nach Grün: das erfolgreiche Ausführen der Tests

2.4.5 Test-Code-Gestaltung

2.5 Refactoring zu parametrisierten Tests

2.6 Weitere NUnit​-Attribute

2.6.1 Aufbau​ und Abbau​

2.6.2 Auf erwartete Ausnahmen​ prüfen

2.6.3 Das Ignorieren​ von Tests

2.6.4 Die fließende Syntax von NUnit

2.6.5 Das Festlegen der Testkategorie​n

2.7 Das Testen auf Zustandsänderungen des Systems statt auf Rückgabewerte

2.8 Zusammenfassung

Teil II: Zentrale Methoden

Kapitel 3: Die Verwendung von Stubs, um Abhängigkeiten aufzulösen

3.1 Die Stubs werden vorgestellt

3.2 Die Identifizierung einer Dateisystemabhängigkeit in LogAn

3.3 Die Entscheidung, wie LogAnalyzer am einfachsten getestet werden kann

3.4 Design-Refactoring zur Verbesserung der Testbarkeit​

3.4.1 Extrahiere ein Interface​, um die dahinter liegende Implementierung durch eine andere ersetzen zu können

3.4.2 Dependency Injection: Injiziere eine Fake-Implementierung​ in die zu testende Unit

3.4.3 Injiziere einen Fake auf Konstruktor-Ebene (Construktor Injectio​n)

3.4.4 Simuliere Ausnahmen über Fakes

3.4.5 Injiziere ein Fake als Property Get oder Set

3.4.6 Injiziere einen Fake unmittelbar vor einem Methodenaufruf

3.5 Variationen der Refactoring​-Technik

3.5.1 Die Verwendung von Extract and Override​, um Fake-Resultate zu erzeugen

3.6 Die Überwindung des Kapselungsproblems​

3.6.1 Die Verwendung von internal​ und [InternalsVisibleTo​]

3.6.2 Die Verwendung des Attributs [Conditiona​l]

3.6.3 Die Verwendung von #if und #endif zur bedingten Kompilierung​​

3.7 Zusammenfassung

Kapitel 4: Interaction Testing mit Mock-Objekten

4.1 Wertbasiertes Testen versus zustandsbasiertes Testen versus Testen versus Interaction Testing

4.2 Der Unterschied zwischen Mocks​ und Stubs​

4.3 Ein einfaches manuelles Mock-Beispiel

4.4 Die gemeinsame Verwendung von Mock​ und Stub​

4.5 Ein Mock​ pro Test

4.6 Fake-Ketten​​: Stubs, die Mocks oder andere Stubs erzeugen

4.7 Die Probleme mit handgeschriebenen Mocks​ und Stubs​

4.8 Zusammenfassung

Kapitel 5: Isolation-(Mock-Objekt-)Frameworks

5.1 Warum überhaupt Isolation-Frameworks?

5.2 Das dynamische Erzeugen eines Fake-Objekts

5.2.1 Die Einführung von NSubstitute in Ihre Tests

5.2.2 Das Ersetzen eines handgeschriebenen Fake-Objekts durch ein dynamisches

5.3 Die Simulation von Fake-Werten

5.3.1 Ein Mock, ein Stub und ein Ausflug in einen Test

5.4 Das Testen auf ereignisbezogene Aktivitäten

5.4.1 Das Testen eines Event Listeners

5.4.2 Der Test, ob ein Event getriggert wurde

5.5 Die aktuellen Isolation-Frameworks für .NET

5.6 Die Vorteile und Fallstricke von Isolation-Frameworks

5.6.1 Fallstricke, die man bei der Verwendung von Isolation-Frameworks besser vermeidet

5.6.2 Unlesbarer Testcode

5.6.3 Die Verifizierung der falschen Dinge

5.6.4 Die Verwendung von mehr als einem Mock pro Test

5.6.5 Die Überspezifizierung​ von Tests

5.7 Zusammenfassung

Kapitel 6: Wir tauchen tiefer ein in die Isolation-Frameworks

6.1 Eingeschränkte und uneingeschränkte Frameworks

6.1.1 Eingeschränkte Frameworks

6.1.2 Uneingeschränkte Frameworks

6.1.3 Wie Profiler-basierte uneingeschränkte Frameworks arbeiten

6.2 Werte guter Isolation-Frameworks

6.3 Eigenschaften, die Zukunftssicherheit und Benutzerfreundlichkeit unterstützen

6.3.1 Rekursive Fakes​​

6.3.2 Ignoriere Argumente als Voreinstellung

6.3.3 Umfangreiches Fälschen

6.3.4 Nicht striktes Verhalten von Fakes

6.3.5 Nicht strikte Mocks

6.4 Isolation-Framework-Design-Antimuster

6.4.1 Konzept-Konfusion

6.4.2 Aufnahme und Wiedergabe

6.4.3 Klebriges Verhalten​​

6.4.4 Komplexe Syntax​​

6.5 Zusammenfassung

Teil III: Der Testcode

Kapitel 7: Testhierarchie und Organisation

7.1 Automatisierte Builds, die automatisierte Tests​ laufen lassen

7.1.1 Die Anatomie eines Build-Skripts

7.1.2 Das Anstoßen von Builds und Integration

7.2 Testentwürfe, die auf Geschwindigkeit und Typ basieren

7.2.1 Der menschliche Faktor beim Trennen von Unit und Integrationstests

7.2.2 Die sichere grüne Zone

7.3 Stellen Sie sicher, dass die Tests zu Ihrer Quellcodekontrolle​ gehören

7.4 Das Abbilden der Testklassen auf den zu testenden Code

7.4.1 Das Abbilden von Tests auf Projekte

7.4.2 Das Abbilden von Tests auf Klassen

7.4.3 Das Abbilden von Tests auf bestimmte Methoden

7.5 Querschnittsbelang-Injektion

7.6 Der Bau einer Test-API für Ihre Applikation

7.6.1 Die Verwendung von Testklassen-Vererbungsmustern

7.6.2 Der Entwurf von Test-Hilfsklassen und -Hilfsmethoden

7.6.3 Machen Sie Ihre API den Entwicklern bekannt

7.7 Zusammenfassung

Kapitel 8: Die Säulen guter Unit Tests

8.1 Das Schreiben vertrauenswürdiger Tests

8.1.1 Die Entscheidung, wann Tests entfernt oder geändert werden

8.1.2 Vermeiden Sie Logik in Tests

8.1.3 Testen Sie nur einen Belang

8.1.4 Trennen Sie Unit Tests von Integrationstests

8.1.5 Stellen Sie Code-Reviews mit Codeabdeckung sicher

8.2 Das Schreiben wartbarer Tests

8.2.1 Das Testen privater oder geschützter Methoden

8.2.2 Das Entfernen von Duplizitäten

8.2.3 Die Verwendung von Setup-Methoden in einer wartbaren Art und Weise

8.2.4 Das Erzwingen der Test-Isolierung

8.2.5 Vermeiden Sie mehrfache Asserts für unterschiedliche Belange

8.2.6 Der Vergleich von Objekten

8.2.7 Vermeiden Sie eine Überspezifizierung​ der Tests

8.3 Das Schreiben lesbarer Tests

8.3.1 Die Benennung der Unit Tests

8.3.2 Die Benennung der Variablen

8.3.3 Benachrichtigen​ Sie sinnvoll

8.3.4 Das Trennen der Asserts von den Aktionen

8.3.5 Aufbauen und Abreißen

8.4 Zusammenfassung

Teil IV: Design und Durchführung

Kapitel 9: Die Integration von Unit Tests in die Organisation

9.1 Schritte, um ein Agent des Wandels zu werden

9.1.1 Seien Sie auf die schweren Fragen vorbereitet

9.1.2 Überzeugen Sie Insider​: Champions​ und Blockierer

9.1.3 Identifizieren Sie mögliche Einstiegspunkte

9.2 Wege zum Erfolg

9.2.1 Guerilla-Implementierung​ (Bottom-up​)

9.2.2 Überzeugen Sie das Management (Top-down)

9.2.3 Holen Sie einen externen Champion

9.2.4 Machen Sie Fortschritte sichtbar

9.2.5 Streben Sie bestimmte Ziele an

9.2.6 Machen Sie sich klar, dass es Hürden geben wird

9.3 Wege zum Misserfolg

9.3.1 Mangelnde Triebkraft

9.3.2 Mangelnde politische Unterstützung

9.3.3 Schlechte Implementierungen und erste Eindrücke

9.3.4 Mangelnde Teamunterstützung

9.4 Einflussfaktoren

9.5 Schwierige Fragen und Antworten

9.5.1 Wie viel zusätzliche Zeit wird der aktuelle Prozess für das Unit Testing benötigen?

9.5.2 Ist mein Job bei der QS in Gefahr wegen des Unit Testing?

9.5.3 Woher wissen wir, dass Unit Tests wirklich funktionieren?

9.5.4 Gibt es denn einen Beweis, dass Unit Testing hilft?

9.5.5 Warum findet die QS​ immer noch Bugs?

9.5.6 Wir haben eine Menge Code ohne Tests: Wo fangen wir an?

9.5.7 Wir arbeiten mit mehreren Sprachen: Ist Unit Testing da praktikabel?

9.5.8 Was ist, wenn wir eine Kombination aus Soft- und Hardware entwickeln?

9.5.9 Wie können wir wissen, dass wir keine Bugs in unseren Tests haben?

9.5.10 Mein Debugger zeigt mir, dass mein Code funktioniert: Wozu brauche ich Tests?

9.5.11 Müssen wir Code im TDD-Stil schreiben?

9.6 Zusammenfassung

Kapitel 10: Der Umgang mit Legacy-Code

10.1 Wo soll man mit dem Einbauen der Tests beginnen?

10.2 Bestimmen Sie eine Auswahlstrategie

10.2.1 Vor- und Nachteile der Strategie »Einfaches zuerst​«

10.2.2 Vor- und Nachteile der Strategie »Schwieriges zuerst​«

10.3 Schreiben Sie Integrationstests, bevor Sie mit dem Refactoring beginnen

10.4 Wichtige Tools für das Unit Testing von Legacy-Code

10.4.1 Abhängigkeiten isolieren Sie leicht mit uneingeschränkten Isolation-Frameworks

10.4.2 Verwenden Sie JMockit für Java-Legacy-Code

10.4.3 Verwenden Sie Vise​ beim Refactoring Ihres Java-Codes

10.4.4 Verwenden Sie Akzeptanztests, bevor Sie mit dem Refactoring beginnen

10.4.5 Lesen Sie das Buch von Michael Feathers zu Legacy-Code

10.4.6 Verwenden Sie NDepend, um Ihren Produktionscode zu untersuchen

10.4.7 Verwenden Sie ReSharper für die Navigation und das Refactoring des Produktionscodes

10.4.8 Spüren Sie Code-Duplikate (und Bugs) mit Simian und TeamCity auf

10.5 Zusammenfassung

Kapitel 11: Design und Testbarkeit

11.1 Warum sollte ich mir Gedanken um die Testbarkeit in meinem Design​ machen?

11.2 Designziele für die Testbarkeit

11.2.1 Deklarieren Sie Methoden standardmäßig als virtuell

11.2.2 Benutzen Sie ein Interface-basiertes Design

11.2.3 Deklarieren Sie Klassen standardmäßig als nicht versiegelt

11.2.4 Vermeiden Sie es, konkrete Klassen innerhalb von Methoden mit Logik zu instanziieren

11.2.5 Vermeiden Sie direkte Aufrufe von statischen Methoden

11.2.6 Vermeiden Sie Konstruktoren und statische Konstruktoren, die Logik enthalten

11.2.7 Trennen Sie die Singleton-Logik und Singleton-Halter

11.3 Vor- und Nachteile des Designs zum Zwecke der Testbarkeit

11.3.1 Arbeitsumfang

11.3.2 Komplexität

11.3.3 Das Preisgeben von sensiblem IP

11.3.4 Manchmal geht’s nicht

11.4 Alternativen des Designs zum Zwecke der Testbarkeit

11.4.1 Design-Argumente und Sprachen mit dynamischen Typen

11.5 Beispiel eines schwer zu testenden Designs

11.6 Zusammenfassung

11.7 Zusätzliche Ressourcen

Anhang A: Tools und Frameworks

A.1 Isolation-Frameworks

A.1.1 Moq

A.1.2 Rhino Mocks

A.1.3 Typemock Isolator

A.1.4 JustMock

A.1.5 Microsoft Fakes (Moles)

A.1.6 NSubstitute

A.1.7 FakeItEasy

A.1.8 Foq

A.1.9 Isolator++

A.2 Test-Frameworks

A.2.1 Mighty Moose (auch bekannt als ContinuousTests) Continuous Runner

A.2.2 NCrunch Continuous Runner

A.2.3 Typemock Isolator Test Runner

A.2.4 CodeRush Test Runner

A.2.5 ReSharper Test Runner

A.2.6 TestDriven.NET Runner

A.2.7 NUnit GUI Runner

A.2.8 MSTest Runner

A.2.9 Pex

A.3 Test-APIs

A.3.1 MSTest-API – Microsofts Unit-Testing-Framework

A.3.2 MSTest für Metro Apps (Windows Store)

A.3.3 NUnit API

A.3.4 xUnit.net

A.3.5 Fluent Assertions Helper API

A.3.6 Shouldly Helper API

A.3.7 SharpTestsEx Helper API

A.3.8 AutoFixture Helper API

A.4 IoC-Container

A.4.1 Autofac

A.4.2 Ninject

A.4.3 Castle Windsor

A.4.4 Microsoft Unity

A.4.5 StructureMap

A.4.6 Microsoft Managed Extensibility Framework

A.5 Datenbanktests

A.5.1 Verwenden Sie Integrationstests für Ihre Datenschicht

A.5.2 Verwenden Sie TransactionScope für ein Rollback der Daten

A.6 Webtests

A.6.1 Ivonna

A.6.2 Team System Web Test

A.6.3 Watir

A.6.4 Selenium WebDriver

A.6.5 Coypu

A.6.6 Capybara

A.6.7 JavaScript-Tests

A.7 UI-Tests (Desktop)

A.8 Thread-bezogene Tests

A.8.1 Microsoft CHESS

A.8.2 Osherove.ThreadTester

A.9 Akzeptanztests

A.9.1 FitNesse

A.9.2 SpecFlow

A.9.3 Cucumber

A.9.4 TickSpec

A.10 API-Frameworks im BDD-Stil

The Art of Unit Testing

Deutsche Ausgabe

Roy Osherove

Übersetzung aus dem Englischen von Olaf Neuendorf

Impressum

Bibliografische Information der Deutschen Nationalbibliothek

Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über <http://dnb.d-nb.de> abrufbar.

ISBN 978-3-8266-8722-8

2. Auflage 2015

www.mitp.de

E-Mail: mitp-verlag@sigloch.de

Telefon: +49 7953 / 7189 - 079

Telefax: +49 7953 / 7189 - 082

Übersetzung der amerikanischen Originalausgabe: Roy Osherove: The Art of Unit Testing: With Examples in C#, Second Edition, ISBN 978-1617290893.

Original English language edition published by Manning Publications, 178 South Hill Drive, Westampton, NJ 08060 USA. Copyright © 2013 by Manning Publications. German edition copyright © 2015 by mitp Verlags GmbH & Co. KG. All rights reserved.

© 2015 mitp-Verlags GmbH & Co. KG

Dieses Werk, einschließlich aller seiner Teile, ist urheberrechtlich geschützt. Jede Verwertung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Dies gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen.

Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Werk berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei zu betrachten wären und daher von jedermann benutzt werden dürften.

Lektorat: Sabine Schulz

Sprachkorrektorat: Petra Heubach-Erdmann, Maren Feilen

Coverbild: © Sebastian Duda, Bildnummer 33776850

electronic publication: III-satz, Husby, www.drei-satz.de

Dieses Ebook verwendet das ePub-Format und ist optimiert für die Nutzung mit dem iBooks-reader auf dem iPad von Apple. Bei der Verwendung anderer Reader kann es zu Darstellungsproblemen kommen.

Der Verlag räumt Ihnen mit dem Kauf des ebooks das Recht ein, die Inhalte im Rahmen des geltenden Urheberrechts zu nutzen. Dieses Werk, einschließlich aller seiner Teile, ist urheberrechtlich geschützt. Jede Verwertung außerhalb der engen Grenzen des Urheherrechtsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Dies gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und Einspeicherung und Verarbeitung in elektronischen Systemen.

Der Verlag schützt seine ebooks vor Missbrauch des Urheberrechts durch ein digitales Rechtemanagement. Bei Kauf im Webshop des Verlages werden die ebooks mit einem nicht sichtbaren digitalen Wasserzeichen individuell pro Nutzer signiert.

Bei Kauf in anderen ebook-Webshops erfolgt die Signatur durch die Shopbetreiber. Angaben zu diesem DRM finden Sie auf den Seiten der jeweiligen Anbieter.

Vorwort zur zweiten Auflage

Es muss im Jahre 2009 gewesen sein. Ich hielt einen Vortrag auf der Norwegian Developers Conference in Oslo. (Ah, Oslo im Juni!) Die Veranstaltung fand in einer großen Sportarena statt. Die Konferenz-Organisatoren unterteilten die überdachte Tribüne in Abschnitte und bauten jeweils ein Podium vor ihnen auf. Dann hängten sie dicke schwarze Stoffbahnen auf und erstellten auf diese Weise acht verschiedene »Konferenzräume«. Ich erinnere mich, dass ich gerade dabei war, meinen Vortrag zu beenden – er handelte von TDD, oder SOLID, oder Astronomie, oder irgendwas – als plötzlich von der Nachbarbühne ein lautes und raues Singen und Gitarrenspiel ertönte.

Die Stoffbahnen hingen so, dass ich zwischen ihnen hindurch spähen und den Burschen auf der Nachbarbühne sehen konnte. Natürlich war es Roy Osherove.

Nun, diejenigen von Ihnen, die mich kennen, wissen, dass das Anstimmen eines Liedes mitten in einem technischen Vortrag über Software zu den Dingen gehört, die ich vielleicht tue, wenn mir danach ist. Als ich mich wieder meinem Publikum zuwandte, dachte ich so bei mir, dass dieser Osherove wohl ein Gleichgesinnter sei und ich ihn besser kennenlernen müsse.

Und ich lernte ihn besser kennen. In der Tat trug er erheblich zu meinem aktuellen Buch Clean Coder bei und unterstützte mich drei Tage lang dabei, einen Kurs in TDD zu geben. Alle meine Erfahrungen mit Roy waren sehr positiv und ich hoffe, es wird noch viele weitere geben.

Ich schätze, dass Ihre Erfahrungen mit Roy beim Lesen dieses Buch auch sehr positiv sein werden, denn dieses Buch ist etwas Besonderes.

Haben Sie jemals einen Roman von Michener gelesen? Ich jedenfalls nicht – aber mir wurde gesagt, sie alle würden »mit dem Atom« beginnen. Das Buch, das Sie in Händen halten, ist kein James-Michener-Roman, aber es beginnt mit dem Atom – dem Atom des Unit Testings.

Lassen Sie sich nicht beirren, wenn Sie die ersten Seiten durchblättern. Dies ist keine bloße Einführung ins Unit Testing. Es beginnt so, aber wenn Sie bereits Erfahrung haben, können Sie diese ersten Kapitel schnell überfliegen. Während das Buch dann aber voranschreitet, beginnen die Kapitel aufeinander aufzubauen und entwickeln eine erstaunliche Tiefe. Und als ich das letzte Kapitel las (ich wusste nicht, dass es das letzte war), dachte ich tatsächlich, dass das nächste wohl vom Weltfrieden handeln müsse – denn im Ernst, womit sonst kann man weitermachen, nachdem man das Problem gelöst hat, Unit Testing in starrsinnige Organisationen mit alten, überkommenen Systemen einzuführen.

Dieses Buch ist ein Fachbuch – und zutiefst ein Fachbuch. Es gibt eine Menge Code. Und das ist gut so. Doch Roy beschränkt sich nicht auf die technischen Aspekte. Gelegentlich holt er seine Gitarre hervor, beginnt zu singen und erzählt Geschichten aus seinem Berufsleben. Oder er stellt philosophische Betrachtungen an über die Bedeutung von Design oder die Definition von Integration. Er scheint Gefallen daran zu finden, uns mit Geschichten aus jenen dunklen, längst vergangenen Tagen des Jahres 2006 zu verwöhnen, als ihm so manches misslungen ist.

Ach, und machen Sie sich keine allzu großen Sorgen, dass der komplette Code in C# geschrieben ist. Im Ernst, wer könnte überhaupt den Unterschied zwischen C# und Java erklären? Oder? Und abgesehen davon spielt es auch keine Rolle. Er mag zwar C# als Vehikel benutzen, um seine Intention klar zu machen, aber die Lektionen in diesem Buch gelten genauso für Java, C, Ruby, Python, PHP oder jede andere Programmiersprache (vielleicht mit Ausnahme von COBOL).

Egal, ob Sie ein Anfänger auf dem Gebiet des Unit Testings und der testgetriebenen Entwicklung sind oder ein alter Hase, dieses Buch hält für Sie alle etwas bereit. Also viel Vergnügen, während Roy für Sie sein Lied singt »The Art of Unit Testing«.

Und bitte Roy, stimme diese Gitarre!

Robert C. Martin (Uncle Bob)
CLEANCODER.COM

Vorwort zur ersten Auflage

Als mir Roy Osherove erzählte, er würde an einem Buch über das Unit Testing arbeiten, war ich sehr froh, dies zu hören. Das Test-Mem ist über die Jahre in der Industrie gewachsen, aber es gibt einen relativen Mangel an Material zum Unit Testing. Wenn ich mein Bücherregal betrachte, dann sehe ich Bücher zur testgetriebenen Entwicklung im Besonderen und Bücher zum Testen im Allgemeinen, aber bis jetzt gab es keine umfassende Referenz zum Unit Testing – kein Buch, das in das Thema einführt, den Leser an die Hand nimmt und von den ersten Schritten bis zu den allgemein akzeptierten besten Vorgehensweisen führt. Diese Tatsache ist verblüffend. Unit Testing ist keine neue Praxis. Wie konnte es dazu kommen?

Es ist beinahe ein Klischee, wenn man sagt, dass wir in einer neuen Industrie arbeiten, aber es ist wahr. Mathematiker legten die Grundlagen unserer Arbeit vor weniger als 100 Jahren, aber erst seit 60 Jahren haben wir die Hardware, die schnell genug ist, um ihre Erkenntnisse auch nutzen zu können. In unserer Industrie bestand von Anfang an eine Lücke zwischen Theorie und Praxis und erst jetzt entdecken wir, wie sich das auf unser Fachgebiet ausgewirkt hat.

In den frühen Jahren waren Rechenzeiten teuer. Wir ließen die Programme im Batchbetrieb laufen. Programmierer hatten ein planmäßiges Zeitfenster, sie mussten ihre Programme in Kartenstapel stanzen und in den Maschinenraum tragen. War ein Programm nicht in Ordnung, hatten sie ihre Zeit vergeudet, also überprüften sie es zuvor mit Papier und Stift am Schreibtisch und gingen in Gedanken alle möglichen Szenarien, alle Grenzfälle durch. Ich bezweifle, dass der Begriff des automatisierten Unit Testings zu dieser Zeit überhaupt vorstellbar war. Warum sollte man die Maschine zum Testen nutzen, wo sie doch zur Lösung bestimmter Probleme gebaut worden war? Der Mangel hielt uns in der Dunkelheit gefangen.

Später wurden die Maschinen schneller und wir berauschten uns am interaktiven Computing. Wir konnten einfach Code eintippen und ihn aus Jux und Tollerei ändern. Die Idee, den Code am Schreibtisch zu überprüfen, schwand allmählich dahin und wir verloren etwas von der Disziplin der frühen Jahre. Wir wussten, dass Programmieren schwierig war, aber das bedeutete nur, dass wir mehr Zeit am Computer verbringen mussten und Zeilen und Symbole änderten, bis wir die magische Zauberformel, die funktionierte, gefunden hatten.

Wir kamen vom Mangel zum Überfluss und verpassten den Mittelweg, aber nun erobern wir ihn zurück. Automatisiertes Unit Testing verbindet die Disziplin der Schreibtischprüfung mit einer neu gefundenen Wertschätzung des Computers als einer Entwicklungsressource. Wir können automatische Tests in der Sprache schreiben, in der wir entwickeln, um unsere Arbeit zu überprüfen – und das nicht nur einmal, sondern so oft wir in der Lage sind, die Tests laufen zu lassen. Ich glaube nicht, dass es irgendein anderes Verfahren in der Softwareentwicklung gibt, das derartig mächtig ist.

Während ich dies im Jahre 2009 schreibe, bin ich froh zu sehen, wie Roys Buch in den Druck geht. Es ist eine praktische Anleitung, die Ihnen helfen wird, loszulegen, und es ist auch eine großartige Referenz, wenn Sie Ihre Aufgaben beim Testing angehen. The Art of Unit Testing ist kein Buch über idealisierte Szenarien. Es zeigt Ihnen, wie man Code testet, der im praktischen Einsatz existiert, wie man Nutzen aus weitverbreiteten Frameworks zieht und – was das Wichtigste ist – wie man Code schreibt, der wesentlich einfacher zu testen ist.

The Art of Unit Testing ist ein wichtiger Titel, der schon vor Jahren hätte geschrieben werden sollen, aber damals waren wir noch nicht bereit dafür. Jetzt sind wir bereit. Genießen Sie es!

Michael Feathers

Senior Consultant
Object Mentor

Einleitung

Eines der größten Projekte, an dem ich mitgearbeitet habe und das schiefgelaufen ist, beinhaltete auch Unit Tests. Das dachte ich zumindest. Ich leitete eine Gruppe von Entwicklern, die an einer Abrechnungssoftware arbeiteten, und wir machten es komplett auf die testgetriebene Weise – wir schrieben zuerst die Tests, dann den Code, die Tests schlugen fehl, wir sorgten dafür, dass sie erfolgreich verliefen, führten ein Refactoring durch und fingen wieder von vorne an.

Die ersten paar Monate des Projekts waren großartig. Alles lief gut und wir hatten Tests, die belegten, dass unser Code funktionierte. Aber im Laufe der Zeit änderten sich die Anforderungen. Wir waren also gezwungen, unseren Code zu ändern, um diesen neuen Anforderungen gerecht zu werden, doch als wir das taten, wurden die Tests unzuverlässig und mussten nachgebessert werden. Der Code funktionierte immer noch, aber die Tests, die wir dafür geschrieben hatten, waren so zerbrechlich, dass jede kleine Änderung in unserem Code sie überforderte, auch wenn der Code selbst prima funktionierte. Die Änderung des Codes in einer Klasse oder Methode wurde zu einer gefürchteten Aufgabe, weil wir auch alle damit zusammenhängenden Unit Tests entsprechend anpassen mussten.

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!