Michael Tamm: JUnit-Profiwissen

Michael Tamm: JUnit-Profiwissen

Michael Tamm
JUnit-Profiwissen. Effizientes Arbeiten mit der Standardbibliothek für automatisierte Tests in Java.

Oktober 2013, 370 Seiten, Broschur
dpunkt.verlag
ISBN 978-3-86490-020-4

Informationen zum Buch im Katalog der Deutschen Nationalbibliothek.



Das Buch JUnit-Profiwissen behandelt eingehend das Framework JUnit in den Versionen 3.8.1 und 4.0-4.11. Durch die detaillierte Betrachtung der Mocking-Bibliotheken jMock, EasyMock, PowerMock und Mockito und der Matcher-Bibliotheken Hamcrest und FEST Fluent Assertions geht der Autor etliche Schritte weiter, als er im Titel suggeriert. Alles in allem handelt es sich bei dem Buch, auch wenn nicht mehr ganz aktuell, um eine empfehlenswerte, bereichernde Lektüre.


Struktur

Das Buch ist in 13 Kapiteln untergliedert plus einer Einführung und einem sehr kurzen Schlusswort, das einen Überblick möglicher Themen für eine zweite Auflage des Buches beinhaltet.

Nach der Einführung in das Thema Testen, werden die Features der Versionen 3 und 4 des JUnit-Frameworks dargestellt (bis 4.11), gefolgt von weiteren, mit dem Testen eng verwandten Bereichen. So wird in Kapitel 4 auf die Themenkomplexe Test Driven Development (TDD) und Acceptance TDD (ATDD) eingegangen, um dann in jeweils eigenen Kapiteln Assertion- und Mocking-Bibliotheken zu behandeln.

Es folgen Kapitel über die Verständlichkeit und Ausführungsgeschwindigkeit von Tests und das Testen schwieriger Fälle sowie das Testen nichtfunktionaler Anforderungen. Die letzten vier Kapitel behandeln die Integration von JUnit in gängigen Entwicklungsumgebungen (Eclipse und IntelliJ IDEA) und Build-Tools (Ant und Maven).

Inhalt

Einführung

Die Einführung gibt einen Überblick unterschiedlicher Testarten. Diese werden anhand diverser Kategorien zusammengefasst:

  • funktional vs. nichtfunktional
  • Black-Box vs. White-Box
  • manuell vs. automatisiert
  • Verwendung von Mocks vs. Verwendung realer Ressourcen
  • Größe der getesteten Komponente: Unit-, Integrations- und Szenariotests
  • Zeitpunkt, wann die Tests geschrieben werden und in wessen Verantwortlichkeit das Schreiben liegt
  • Funktion der Tests: Learning-Tests, um das Verhalten einer verwendeten Bibliothek näher zu verstehen, Regressionstests, um Regressionen zu vermeiden etc.

Für die allermeisten dieser Testarten wird JUnit als angemessenes Tool genannt.

JUnit 3

Bevor der Autor auf die Features von JUnit 4.11 eingeht – die im Erscheinungsjahr des Buches aktuelle Version des Frameworks – präsentiert er den Funktionalitätsumfang der Version 3.8.1 mit der Begründung, dass diese Version noch in vielen Bibliotheken und Frameworks Verwendung finden würde. Um dies zu unterstreichen, verwendet Tamm bei der Beschreibung der einzelnen Konzepte Beispiele aus dem Spring-Framework und aus der Apache Commons IO-Bibliothek. Es werden die eingebauten Assertions, die Grundkonzepte von JUnit samt derer Verwendungsweise präsentiert.

JUnit 4

Neben dem sechsten Kapitel, welches das Thema Mocking behandelt, ist das dritte Kapitel das umfangreichste des Buches. Grundlegende Änderungen des Frameworks, die durch das Einführen von Annotationen in Java 5 möglich gemacht wurden, werden genauso behandelt wie die Themen Rules, Runner, Suiten, Kategorien und Theorien. Vor dem Hintergrund der Integration der Hamcrest-Bibliothek in JUnit wird das Thema Matcher behandelt. Detailliert wird beschrieben, welche Änderungen in welchen Versionen des Frameworks eingeführt wurden, so wurden z.B. in der Version 4.7 Rules eingeführt und in der Version 4.11 wurde von der Version 1.1 der Hamcrest-Bibliothek auf die Version 1.3 umgestiegen.

Rules werden als „Testaspekte“ bezeichnet und mit dem Konzept des Aspekts aus der aspektorientierten Programmierung (AOP) in Verbindung gebracht, wobei das Waving im Gegensatz zu AspectJ manuell gemacht werden muss. JUnit stellt dabei eine Reihe eingebauter Rules zur Verfügung, es besteht jedoch auch die Möglichkeit eigene Rules zu schreiben.

Das Thema Runner wird eingehend behandelt. Die Runner Parametrized, BlockJUnit4ClassRunner (der Standard-Runner der bei fehlender RunWith-Annotation eingesetzt wird), Suite, Theories und Categories werden detailliert besprochen. Es wird dabei auch auf die Konzepte der Theorien, Kategorien und Assumptions und deren Verwendung eingegangen. Zusätzlich wird auch die Möglichkeit eigene Runner zu schreiben nicht vernachlässigt.

Das Kapitel schließt mit einer umfangreichen Diskussion über die Art wie mit der Ignore-Annotation umgegangen werden kann und nach Meinung des Autors soll.

Die einzelnen Aspekte, Konzepte und Funktionalitäten werden durch viele Beispiele, die größtenteils aus Open-Source-Projekten stammen, verdeutlicht. So sind im Kapitel Code-Schnipsel aus den Projekten Solr, Lucene, Hadoop, Guava, Selenium, EhCache und andere zu finden.

Testgetriebene Entwicklung

Das vierte Kapitel behandelt, wie es der Titel schon sagt das Thema TDD. Dabei wird auch kurz auf das Thema Behavior Driven Development (BDD) und umfangreicher auf das Thema ATDD, welches als Einbettungskontext für TDD dargestellt wird, eingegangen. Die Themen Code-Review und Refactoring, sowohl manuell als auch mithilfe von Toolunterstützung, werden angeschnitten. In diesem Kontext werden Hilfstools wie FindBugs, Checkstyle, PMD und andere erwähnt. Der Autor zeigt sich dabei als überzeugter Praktizierender des TDD.

Assertion-Bibliotheken

Im Kapitel “Assertion-Bibliotheken” präsentiert Tamm zwei Libraries für Assertions: Hamcrest, eine Bibliothek, die teilweise in JUnit integriert wurde und FEST Fluent Assertions. Weitere Bibliotheken wie Truth und Dotmesh werden lediglich erwähnt. Die Verwendungsweise beider Bibliotheken wird gezeigt, im Falle von Hamcrest findet auch eine Betrachtung einiger Implementierungsdetails der Library statt. Im Falle der Fluent Assertions wird die wahrgenommene Ästhetik der Schnittstelle wiederholt hervorgehoben.

Unit-Tests mit Mock-Objekten

Dem Bereich Mocking widmet der Autor über 60 Seiten, was angesichts der Wichtigkeit dieses Themas aber nicht weiter verwunderlich ist. Begonnen wird mit der Nomenklatur des Mockings. Es wird unterschieden zwischen: Dummy-, Pseudo-, Fake-, Stub-, Mock- und Spy-Objekten, der Saboteur wird als Unterkategorie des Stubs präsentiert. Die Verwendung dreier Mocking-Bibliotheken wird beschrieben, wobei teilweise auch auf Unterschiede zwischen den einzelnen Versionen innerhalb einer Bibliothek eingegangen wird. Diese Bibliotheken sind: jMock, EasyMock und Mockito. Zum Schluss des Kapitels wird die Frage aufgeworfen, wie statische Methoden getestet werden können. Das Framework PowerMock wird als mögliche Lösung präsentiert, das durch Bytecodemanipulation der zu mockenden Klassen über einen speziellen ClassLoader in der Lage ist, statische, finale und private Eigenschaften und Methoden „mockbar“ zu machen.

Programmieren gut verständlicher Tests

Unter „Verständlichkeit“ versteht der Autor Konventionen, die einzuhalten sind, um die Les- und Wartbarkeit der Tests sicherzustellen. So sind neben Namenskonventionen für Testklassen und -methoden ebenfalls die Formulierung von Assertion-Messages und die Dreiteilung der Tests in jeweils einem Arrange-, Act- und Assert-Teil (AAA) wichtig. Der Autor geht so weit, dass er „Kein Test ohne Assertion“ (S. 220) fordert. Das Kapitel betrachtet weiterhin den Enclosed-Runner und die Test Data Builder- und Page Object-Muster.

Programmieren schneller Tests

Ausführgeschwindigkeit wird als wichtiges Kriterium für Testsuiten betrachtet. Der Autor gibt als Richtwert für die Dauer eines Builds 10 Minuten an. Über diese Grenze sollten Ressourcen in die Optimierung der Tests investiert werden. Das Kapitel „Programmieren schneller Tests“ betrachtet etliche Optimierungsmöglichkeiten:

  • durch die Beschleunigung einzelner Tests,
  • durch die Beschleunigung der Testfixtures,
  • durch einmaliges Ausführen der Before– und After-Blocks als BeforeClass– respektive AfterClass-Blöcke,
  • durch paralleles Ausführen der Tests,
  • durch Verschieben der Klassen-Fixtures auf Suitenebene (Shared Testfixture Pattern),
  • durch eine geeignete Ausführungsreihenfolge, die zwar die Gesamtgeschwindigkeit nicht erhöht, aber ein schnelles Feedback ermöglicht (Tests, die am ehesten fehlschlagen könnten, sollen als erste ausgeführt werden).

Tests abseits des Happy Paths

Im 9. Kapitel behandelt der Autor schwieriger zu testenden Themen, die aber nichtsdestotrotz wichtig zu testen sind:

  • Verhalten bei Exceptions,
  • Testen von (nichttrivialen) Logmeldungen,
  • Testen von Ausgaben auf den System-Streams,
  • Und das Testen von System.exit.

Nichtfunktionale Tests

Nichtfunktionalen Tests als spezielle Fälle “abseits des Happy Paths,” werden in diesem Kapitel betrachtet. Auch wenn JUnit zum Testen funktionaler Aspekte entwickelt wurde, eignet es sich ebenfalls zum Testen nichtfunktionaler Aspekte, was der Autor anhand vieler Beispiele zeigt. Folgende Themen werden durchgenommen:

  • Performance-Testing inklusive Möglichkeiten zum Micro-Benchmarking,
  • Erstellen von Stresstests, speziell Lasttests und Fuzzytests,
  • Möglichkeiten zu Randomized Testing,
  • Und Architekturtests, wobei an dieser Stelle auch viele dedizierte Tools wie Checkstyle, PMD, ConQAT, Findbugs und JDepend Erwähnung finden.

Integration von JUnit in diversen Tools

Die letzten vier Kapiteln behandeln die Integration von JUnit in IDEs (Eclipse und IntelliJ IDEA) und Build-Tools (Ant und Maven). Es werden für jedes dieser Tools nebst den integrierten Funktionalitäten vorhandene Plugins vorgestellt. Dabei werden auch Möglichkeiten zum Messen der Testabdeckung (EclEmma, EMMA, Cobertura, JaCoCo) diskutiert und im Falle von IntelliJ IDEA die Unterschiede bzgl. Testing zwischen der Community- und der Ultimate-Edition vorgestellt. Zum Schluss wird auch auf die Ausführung von Integrationstests mittels der dedizierten Maven-Phase integration-test eingegangen.

Diskussion

Michael Tamm verspricht nicht zu viel, als er in der Vorrede schreibt, dass auch erfahrene JUnit-Kenner aus dem Buch Nutzen ziehen können. Für Java-Entwickler konzipiert, eignet sich der Stoff sowohl für wenig erfahrene (oder gar komplett unerfahrene) JUnit-Anwender, als auch für Profis – in diesem Sinne ist der Titel gut gewählt: JUnit-Profiwissen. Es besteht jedoch das Risiko, dass die Unerfahrenen durch die Fülle an Information überfordert werden, während die Profis bei den Grundlagen ins Gähnen kommen. Dies ist jedoch ein generelles Risiko bei einem derartig breit aufgestelltem Buch.

Gleichzeitig ist der Buchtitel aber auch irreleitend. Es geht nämlich in dem Buch um soviel mehr als nur um JUnit. Es geht ebenfalls um Matching- und Mocking-Bibliotheken und es geht nicht nur um Unit-Testing, da auch das Thema nichtfunktionale Tests angegangen wird. Das Buch gibt mehr, als es durch den Titel verspricht, aber nicht genug, um es zum Beispiel Testing in Java zu nennen. Nichtsdestotrotz sind die Samen für weiteres Wachstum gesät und es wäre schön eine zweite erweiterte Auflage des Buches, die sich in Richtung „Testing in Java“ bewegt, in den Händen halten zu können.

Dass der Autor selbst solche Gedanken gehegt hat, ist dem Schlusswort zu entnehmen, wo er weitere Themen auflistet, die ihm am Herzen liegen: JUnit und Gradle, Integration von JUnit in CI-Servern, Mutation-Testing, JUnit und Groovy und einiges mehr. Während das Behandeln des Themas JUnit und Groovy die Thematik in Richtung „Software-Testing“ bewegen würden, wären die anderen Punkte sinnvolle Erweiterungen des aktuellen Stoffes. Zusätzlich dürfte aus einer aktuellen Ausgabe natürlich eine Besprechung von JUnit 5.x und 4.12 und 4.13 nicht fehlen (auf JUnit 3 könnte wahrscheinlich mittlerweile verzichtet werden). Ebenso wäre eine tiefere Betrachtung des PowerMock-Frameworks interessant und der Vollständigkeit halber vielleicht auch ein Kapitel über die Integration von JUnit in der IDE NetBeans.

Der Text sticht durch viele Beispiele hervor, die oft aus Open-Source-Projekten stammen, das Arbeiten mit realem Code ist immer spannender als mit konstruierten Beispielen. Die Zusammenfassungen am Ende jedes Kapitels machen die Wiederholung des Stoffes einfach.

Alles in allem handelt es sich bei dem Buch, auch wenn nicht mehr ganz aktuell, um eine empfehlenswerte, bereichernde Lektüre.


Zum Autor

Michael Tamm hat mehr als 20 Jahre Erfahrung als Softwareentwickler und -architekt in mehreren Berliner Unternehmen. Neben seinem bislang einzigen Buch JUnit-Profiwissen hat er diverse Fachartikel publiziert und Vorträge auf diversen IT-Konferenzen gehalten. Zusätzlich ist er als Committer diverser Open-Source-Projekte tätig.


Folgende Bücher könnten Sie ebenfalls interessieren:

Petre Sora

Petre Soras Interessen sind vielfältig und befinden sich an der Schnittstelle zwischen Mensch und Informationstechnologie. Als studierter Psychologe und Software Engineer war er knappe sechs Jahre als Java-Entwickler in mehreren Unternehmen tätig. Mit der Gründung der Rezensionsplattform nososo hat er sich entschieden eigene Wege zu gehen. Petre ist als Rezensent und Verfasser von Artikeln für nososo tätig.

Schreibe einen Kommentar