Buch-Rezension zu „Test Driven“

Test Driven
Test Driven

„Test Driven – Practical TDD and Acceptance TDD for Java Developers“ von Lasse Koskela ist Ende 2007 bei Manning erschienen. Bei Test Driven geht es um die testgetriebene Software-Entwicklung in Java.

 
Teil 1: Grundlagen von TDD
Im ersten Kapitel werden die Ideen hinter Test Driven Development (TDD) vorgestellt und erklärt, wieso man als Entwickler davon profitiert. Der Initialaufwand für TDD ist höher als bei der Entwicklung ohne Tests. Doch soll der Code irgendwann in Produktion, muss dieser getestet werden. Und wenn man Tests eh braucht, kann man die auch zu einer Zeit schreiben, von der man selber noch etwas davon hat.
Koskela zeigt dabei auch die Wichtigkeit von Refactoring auf. Ohne Tests wird darauf zu oft verzichtet. Der Code läuft, wieso durch eine Änderung neue Probleme riskieren? Hat man die TDD Tests, passen diese auf das beibehalten der Funktionalität auf. Und Refactoring ist bei TDD zentral: Hält man sich an die Vorschläge im Buch und versucht immer die einfachste Lösung zum bestehen der Tests zu schreiben, hat man meistens eine fragwürdige Qualität. Erst das Refactoring macht aus dem funktionierenden auch guten Code – dies gilt auch für die Tests. Kapitel 3 widmet sich daher vollständig dem Refactoring.

Die konkrete Umsetzung von TDD wird in den restlichen Kapiteln des 1. Teils mit der Entwicklung einer Template Engine vorgestellt.

 
Teil 2: TDD für spezifische Technologien
Im zweiten Teil geht es um die Anwendung von TDD bei spezifischen Technologien. Dies reicht von Webkomponenten über Datenzugriff bis zu Swing. Ansätze zum Testen von Multi-Thread Programmen und Zeitfunktionen werden ebenfalls anschaulich erklärt. Eine kurze Vorstellung der dafür benutzten Technologien (wie JSP, JDBC, Hibernate, DbUnit, usw.) sowie deren Verwendung zum Testen runden diesen Teil ab.

 
Teil 3: Acceptance TDD
Im letzten Teil werden die Akzeptanz-Tests behandelt. Es wird mit einer Erklärung der Grundbegriffe und Möglichkeiten fürs Vorgehen begonnen und geht dann zur Umsetzung mittels Fit. Der Kunde kann mit der Hilfe von Fit seine Anwendungsfälle in Tabellenform erfassen. Diese dienen dann als Input für Tests und ermöglichen so die Verifizierung der Funktionalität. Damit dies funktioniert muss der Entwickler die Verbindung zwischen Fit und den Unit-Tests erstellen.

 
Fazit:
Test Driven erklärt auf verständliche Art was die testgetriebene Entwicklung ausmacht und wieso man diese anwenden soll. Kapitel 1 und 3 behandeln Grundlagen die auch ausserhalb von Java gelten.
Ich finde das Buch ist sehr gut geschrieben und ich konnte beim lesen nicht genug bekommen. Der dritte Teil kommt nicht ganz an die 2 ersten Teile heran. Da wäre mehr zur Verknüpfung von Fit um den Tests sowie Beispiele mit anderen Frameworks hilfreich gewesen. Dennoch kann ich das Buch ohne Einschränkung weiterempfehlen.

Zum Buch
Test Driven – Practical TDD and Acceptance TDD for Java Developers von Lasse Koskela, 2007 Manning, ISBN 978-1-932394-85-6, 544 Seiten

Leichter debuggen mit DebuggerDisplay

Der Debugger von VisualStudio zeigt einem einen Tooltip an, sobald man mit der Maus über eine Variable oder eine Klasse fährt. Je nach dem ist dieser Text mehr oder weniger hilfreich. Man hat zwar immer die Möglichkeit, die einzelnen Felder und verschachtelten Werte durchzuklicken, bis man die gewünschten Werte angezeigt bekommt. Je grösser die Klasse und je mehr Felder diese beinhaltet, desto unübersichtlicher und mühsamer wird es.

Als kleines Beispiel dient mir eine Klasse Person. Dieses repräsentiert einen Menschen und der Vor- und Nachname sind die Informationen, über die ich das Objekt zuordnen kann. Beim debuggen wäre es für mich hilfreich, genau diese Informationen im Tooltip angezeigt zu bekommen (und eine Id, sollten mehrere Personen den gleichen Namen haben). Eine ganz einfache Personenklasse kann so aussehen:

using System;

namespace DebuggerInfo
{
    class PersonBasic
    {
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public int Id { get; set; }

        public PersonBasic(String firstName, String lastName, int id)
        {
            FirstName = firstName;
            LastName = lastName;
            Id = id;
        }
    }
}

Als Tooltip wird nur der Namespace und Klassenname gezeigt:

Tooltip mit Klassennamen

Wie kann ich nun eine bessere Beschreibung bekommen?

 
Option 1: ToString() überschreiben

Die einfachste Möglichkeit um die gewünschte Anzeige zu erhalten ist das überschreiben der ToString-Methode. Dazu genügt dieses kleine zusätzliche Stück Code:

public override string ToString()
{
    return String.Format("{0} {1} {2}", FirstName, LastName, Id);
}

Der Debugger nutzt nun die ToString-Methode und liefert mir eine hilfreiche Anzeige zurück:
Tooltip mit ToString

 
Option 2: Attribut DebuggerDisplay

Ist die ToString-Methode schon überschrieben und liefert nicht die gewünschten Informationen, kann mit dem Attribut DebuggerDisplay auf Ebene der Klasse die Anzeige im Debugger geändert werden. Dies befindet sich im Namespace System.Diagnostics. Der dazugehörende Code sieht so aus:

namespace DebuggerInfo
{
    [DebuggerDisplay("Person: {LastName} {FirstName}")]
    class PersonDebug
    {
        // Klassendefinition
    }
}

Im Debugger gibt es das gewünschte Ergebnis:

Tooltip mit DebuggDisplay

 

Fazit:
DebuggerDisplay kann einem helfen, gewünschte Informationen nur für den Debugger aufzubereiten. Eine sinnvolle ToString-Methode sollte aber zu erst erstellt werden.

Buch-Rezension zu „Produktiv programmieren“

Produktiv programmieren
Produktiv programmieren
„Produktivität ist das Verhältnis zwischen einer Menge nützlicher Arbeit und der dafür benötigten Zeit.“

Mit dieser Definition beginnt Neal Ford sein Buch „Produktiver programmieren“. Er beobachtete wie die Produktivität der Programmierer über die Jahre abgenommen hat. Dies obwohl immer mehr Werkzeuge gerade diese steigern sollte. Als erstes Beispiel dient die Adressvervollständigung des Browsers. Jeder nutzt Webbrowser, doch wie viele verwenden die Vervollständigung?

Viele Kleinigkeiten die einem das Leben erleichtern würden werden nicht genutzt. Hier setzt Ford an und will zeigen, wie man bei der täglichen Arbeit produktiver werden kann. Das Buch besteht aus den zwei Teilen Mechanismen (Die Prinzipien der Produktivität) und Praxis (Philosophie).

Die Mechanismen beinhalten Beschleuniger (Launcher, Makros), die Fokussierung, Automatisierung und das Verhindern von Wiederholungen (DRY).
Der Teil Philosophie reicht von Testgetriebenem Design (TDD), über statische Codeanalyse, Kapselung, YAGNI (You ain’t gonna need it) bis hin zu Meta-Programmierung.

Die Beispiele sind dabei nicht auf ein spezielles Programm oder Betriebssystem limitiert. Ob für Linux, Mac oder Windows, Eclipse oder Visual Studio – für alles gibt es entsprechende Tipps.

Die grosse Anzahl an Themen bei nur 270 Seiten bedeutet leider, dass vieles nur kurz angeschnitten werden kann. Fords Buch liefert eine gute Übersicht und ermöglicht einem die Themen in einem Kontext zu sehen. Wozu testgetriebenes Design dient, wieso DRY wichtig ist und wohin das nicht beachten von YAGNI führt wird verständlich aufgezeigt. Die Tipps zur Produktivitätssteigerung ermutigen einem bei seiner täglichen Arbeit nach Optimierungen zu suchen.

Wer eine detaillierte Einführung in eines der behandelten Themen will, wird mit diesem Buch nicht zufrieden sein. Wer allerdings ein Übersicht und Tipps zur Produktivitätssteigerung sucht, für den kann ich dieses Buch empfehlen.

Zum Buch
Produktiv programmieren von Neil Ford – Deutsche Übersetzung von Jörg Staudenmeyer, O’Reilly 2008, ISBN 978-3-89721-886-4, 270 Seiten

SVN: Commits auf Tags?

Letzte Woche kam eine interessante Frage auf: welche Version bekommt man in SVN, wenn man auf ein Tag wechselt, auf dies jemand einen Commit ausführte? Ist es die Version bei der man den Tag erstellte oder die letzte Änderung darin?

Bekommt man in der Situation Revision 2 oder 3?
Bekommt man in der Situation Revision 2 oder 3?

Ein wenig über die Begriffe
SVN ist ein Tool zur Versionierung von Dateien (Sourcecode, Texte, Bilder, usw.).
Mit Hilfe von Tags können in SVN spezifische Versionsstände mit einem eindeutigen Namen markiert werden. Als Beispiel kann die Übergabe der Entwicklung an die Tester mit „v1.0.2_to_test“ markiert werden. Dieser Name ist einfacher zu merken als die Revisionsnummer 13478.
Ein Branch ist ein Entwicklungszweig. Dieser läuft getrennt vom Trunk, der Hauptentwicklung. Branches kann man zur Versionswartung nutzen. Hat man seine Version 1 veröffentlicht und findet während der Arbeit an Version 2 einen Bug in v1, kann man den Branch nutzen um auf der Code-Basis von v1 den Fehler zu beheben. Dazu wechselt man vom Trunk in den Branch, macht seine Änderung und committed diese in den Branch. Wikipedia hat dazu noch mehr.

Zurück zur Frage
Was passiert nun, wenn man auf den Tag wechselt und dort eine Änderung committed? Man also ein Tag als Branch benutzt?

Intern macht SVN selber keinen Unterschied zwischen einem Tag und einem Branch. Je nach SVN-Client bekommt man aber vor dem commit eine Warnung:

TortoiseSVN warnt vor commit auf ein Tag
TortoiseSVN warnt vor commit auf ein Tag

Hat man dann aber erst einmal den commit ausgeführt, gibt es keinen Unterschied mehr zwischen Tag und Branch. Diese liegen dann – je nach gewählter Struktur – nur in unterschiedlichen Verzeichnissen.

Ein Update auf den Tag bringt einem somit die letzte Version von diesem „Branch“. Wenn man sich also den Aufwand macht und getrennte Verzeichnisse für Tags und Branches nutzt, sollte man dann auch entsprechend damit arbeiten: Also keine commits auf einen Tag.