Author Archives: hhensel

MyCode extends TestCase

Sie haben sicher auch schon davon gehört:

TDD – Test Driven Development

Ein Mythos? Alle haben schon davon gehört, aber keiner glaubt es so recht? Aber man kennt jemanden, der jemanden kennt …

Das echte Leben

Auf der letzen Symfony Konferenz in Berlin wurde es wieder einmal deutlich: Softwarequalität === Gesundheit, so der Titel des Talks von Roland Golla, über den man mehr erfährt auf blog.nevercodealone.de. Die Kernaussage: Viele Entwickler leiden unter ihren Arbeitsbedingungen. Und die Erkenntnis gegen Ende des Talks (nach der Frage “Wem geht es ebenso?”): Es sind viel zu viele! Von geschätzt 150 Leuten, heben gefühlt alle die Hand! Auf die Gegenfrage, “Bei wem ist es anders/besser?”, melden sich drei. Drei!

Eine echte Alternative …

Tests! Vor allem Unit Tests aus Sicht der Entwickler. Aber auch Component, Integration, Acceptance oder Regression Tests. Hauptsache automatisierbar, damit am Ende so wenig wie möglich manuell passieren muss.

Ja, das Management scheut sich. Ja, gute Tests sind schwer zu schreiben. Ja, man muss besonders diese Fähigkeit mühsam erlernen. Aber es lohnt sich! Ein guter Begleiter auf dem Weg dorthin ist das Buch “xUnit Test Patterns”. Über 800 Seiten. Jede einzelne lesenswert. Großen Respekt an den Autor Gerard Meszaros! Und wie im Buch benannt, braucht es viele “Learning Tests” – dort etwas anders gemeint, aber finden Sie das lieber selber heraus! Warum?

… für ein besseres Leben

Ich erinnere mich gut! Das erstmal, als “alles zerfiel”! Es war fantastisch!

Komplexe Aufgaben, die man nicht im Vorraus vollständig überblicken kann, sind ein Problem. Man ist während des Schreibens der Lösung mit dem Problem beschäftigt. Das ist schwer genug und braucht die volle Aufmerksamkeit. Da ist kein Platz für Design Patterns und Best Practices. Natürlich arbeitet man so strukturiert wie möglich und es wird vielleicht nicht völliger Murks. Aber damit es brauchbar und “haltbar” wird, muss man noch einige Male drüber gehen (refactorn) und Tests schreiben. Manches Mal freut man sich, wenn dann die Einzelteile besser entkoppelt werden und die Tests gut sind. Wenn man denn überhaupt Zeit dafür hat. Oft bleibt es aber auch so. Die Zeit und das Management drängt.

Wenn man aber tatsächlich und konsequent (etwa wie unten beschrieben) per TDD entwickelt, kehrt sich der Prozess plötzlich um. Die Einzelteile entkoppeln sich im Vorfeld, die Tests zwingen sie dazu. Die Tests zwingen auch den Entwickler dazu, sauber zu arbeiten. Alles zerfällt in gut zu handhabende Komponenten, die leicht zu verstehen und schön anzusehen sind. Modularer Code in guter Qualität entsteht, auf den jeder Entwickler zu recht stolz sein kann. Aber vor allem geht das anschließende Refactoring auf ein Minimum zurück, da das meiste der notwendigen Anpassungen bereits während der ersten Implementierung gespart wurde. Wie gesagt: Tests erzwingen gutes Arbeiten. Und dadurch wird man schnell und sicher!

Im Endeffekt werden durch TDD Projekte zeitlich besser planbar. Natürlich auch, weil man “schneller arbeitet”. Das ist aber nicht der wesentliche Punkt. Vor allem entsteht modularer, gut wartbarer Code. Und die ständigen Anpassungen und Erweiterungen fallen somit leicht und sind zeitlich planbar und unproblematisch. Der sonst enorme Faktor “Legacy Code” und das arbeitem mit diesem reduziert sich auf ein Minimum.

Daher stimmt leider die Definition: “Code ohne Tests ist Legacy Code”! Wenn doch bloß das Management das begreift…

Wie kam ich dorthin?

Bis vor einiger Zeit war ich noch der Meinung “Ich schreibe meine Tests lieber nach dem Code”. Kurz danach und mit hoher Coverage, aber danach. TDD liegt mir nicht, dachte ich.

Dann habe ich mich eines Tages dran gesetzt. Inspiriert durch “Uncle Bobs” Talk über “The Transformation Priority Premise” entschloss ich mich, TDD einmal “nach Lehrbuch” zu versuchen. Die Möglichkeiten schienen doch zu verlockend.

Aber, wie beginnen? Na gut, schreib ich mal einen Test. Eine Klasse, eine Methode und ein “assertTrue(true)” später, hatte ich einen grünen Test. Sinnlos, also fragte ich mich “Was will ich den testen?” Verhalten, nicht State, soviel war klar. Na gut, schreib ich halt mal was hin: “sut = new SomeClass(); result = sut.doSomething(); assert(result)”. Ein roter Test, gut. Und plötzlich ging es los:

  • Ich musste überlegen, wie ich die Klasse nenne. Woführ ist sie zuständig, diese eine Sache a la SRP?
  • Wie soll die Methode heißen? Was soll sie ganau tun, welchen Input (Parameter) braucht sie dafür?
  • Vor allem musste ich mir klar werden, was ich als Ergebnis erwarte. Welchen Rückgabewert wollte ich?

Ohne es zu merken begann ich in Design zu denken. Ich war plötzlich in der Lage, all die mir bekannten Best Practices und Design Patterns in Worte (Code) zu fassen. Und es war leicht, weil ich mich noch nicht um die Implementierung kümmern musste, sonder das große ganze beschreiben konnte. Als ich zufrieden war mit der Beschreibung, hatte ich einen aussagekräftigen, roten Test und machte mich an die Umsetzung. In kürzester Zeit hatte ich die Funktionalität fertig und der Test war grün.

Die nächsten Tests fielen mir leichter, die nächtenTage und Wochen habe ich mehr und mehr so gearbeitet und mitlerweile entwickle ich eigentlich nur noch “test driven”. Oft fange ich mit Integrationstests an, welche die Benutzung einer Komponente beschreiben. Diese beinhalten dann etliche Assertions und sind natürlich nicht das Ziel. Aber auf dem Weg zum Ziel finden diese Assertions ihren Weg in die entsprechenden Unit Tests und der Integrationtest schrumpt auf eine gesunde Größe. Er zeigt dann nur noch, dass und wie sich die jeweiligen Komponenten zusammenfügen lassen.

Mittlerweile läuft es fast automatisch. Ich schreibe oft erst ein Haufen Interfaces, welche zeigen “wer wie mit wem” kommuniziert und wo aus Sicht der Architektur Boundaries verlaufen. Meist fürhrt mich mein Weg über Integrationstest über Komponententests zu den eigentlichen Unit Tests. (Gute IDEs sind dabei eine echte Hilfe, daher habe ich auch das gesamte Paket von JetBrains. Und Ich kriege nichts von “denen” sondern bezahle dafür. In meiner Firma und privat. Und das gerne.) Mein Dank gilt dann auch den vielen Autoren, welche sich in den letzten Jahrzehnten die Mühe gemacht haben, ihr Wissen zu verbreiten. Es sind zu viele, um sie alle zu bennen, aber vielleicht sind Robert C. Martin, Martin Fowler, Gerard Meszaros und Greg Young ein paar interesannte Namen.

Das schöne an TDD

Es existiert wirklich!

Man schreibt mehr, aber man entwickelt schneller. Am Ende schreibt wohl weniger, man löscht halt nich mehr so viel. Irgendwie so. Gefühlt brauche ich per TDD die Hälfte oder ein Drittel der Zeit für Aufgaben im Vergleich zum “Tests nach dem Code” Vorgehen. Ich kann mittlerweile fast nicht mehr anders. Und ich kann es endlich aus eigener Erfahrung bestätigen!

Es macht Spaß. Es ist sicher. Es entspannt. Es wird gut.

MyCode extends TestCase bzw. MyTestCase drives MyCode!

Fünf Jahre

Ach herrje! Wir haben hier seit fünf Jahren nichts gepostet!

Wer ist eigentlich “wir”?

“Wir” sind “Hr. Pluralis” und “Fr. Majestatis”. Wir sprechen immer von “wir”, wenn “wir” nicht konkret auf Personen eingehen wollen. Nicht, weil “wir” uns für Monarch(en) halten – eher, weil wir niemandem auf den Schlips treten wollen. Mal schauen, ob ich das zukünftig ändere…

Warum die lange Pause?

Nicht, weil es nichts zu erzählen gäbe – eher, weil wir/ich etwas “off balance” war. Soll heißen, zu viel zu tun bei zu wenig Zeit. Aber Zeit muss man sich nehmen. Für die wichtigen Dinge. In seinem Leben. Also achte ich jetzt vermehrt auf “unsere”

Work – Life – Balance

Ich hoffe, dazu wird auch gehören, hier mehr zu schreiben – aber ich verspreche nichts … 😉

Keiner mehr da …

Support-Mitarbeiter zum Anrufer:

“Ist denn der Cursor noch da?”

Antwort:

“Keine Ahnung. Ich bin hier ganz allein.”

Refactoring, Merkmal professioneller Softwareentwicklung

Als Refactoring bezeichnet man die Veränderung von Quellcode, ohne dass sich das Verhalten der betroffenen Software nach außen ändert. Der geneigte Kunde, Auftraggeber oder Nutzer fragt sich daher oft, was das Ganze soll. Die Antwort ist einfach, aber nicht trivial: Durch Refactoring wird bestehender Code für Entwickler besser verstehbar und ist daher besser wartbar. Zukünftige Veränderungen werden hierdurch leichter, oft sogar überhaupt erst sinnvoll möglich. Warum aber schreiben Entwickler Software dann nicht von Anfang an so?

Stellen Sie sich vor, Sie schreiben einen wichtigen Brief, einen Artikel oder gar ein ganzes Buch. Sie werden mit einem Entwurf beginnen und sich nach und nach an die endgültige Fassung heran tasten. Ihnen ist klar, dass es unmöglich ist, die endgültige Version in einem Rutsch zu schreiben. Und selbst nach Fertigstellung werden Sie hier und da noch Stellen finden, mit denen Sie unzufrieden sind oder die Sie heute anders schreiben würden.

So verhält es sich auch mit der Softwareentwicklung. Man beginnt mit einer ersten Planung, welche die Strukturen der Software darstellen. Sobald diese fest stehen, werden die einzelnen Bestandteile erstellt und zu einer lauffähige Software zusammen gebaut. Hierbei neigt man dazu, relativ große und unübersichtliche Codeblöcke zu schreiben, welche man im Moment hervorragend überblickt. Kommt man aber nach zwei Wochen wieder an diese Stelle, weiß man kaum mehr, worum es geht oder was die Software an dieser Stelle tut. Geschweige denn, wer “diesen Wust verzapft hat”… 😉

Als Autor muss man also nach der ersten Fertigstellung des jeweiligen Softwarebereichs (oder eben des Abschnitts im Buch), diesen überarbeiten, so dass er auch in Zukunft und von anderen Entwicklern leicht verstanden werden kann. Ebenso achtet man darauf, dass man eine ordentliche Struktur hinterlässt. Sie würden sicherlich auch kein Buch gutheißen, indem zusammengehörende Informationen über verschiedene Kapitel verstreut sind und welches nur schwer und holprig zu lesen ist.

Der einzige Grund, kein Refactoring durchzuführen ist, wenn bestehende Software einwandfrei funktioniert und nicht mehr verändert wird. Dann liest auch niemand mehr den Quellcode oder muss diesen bearbeiten. Da wir Software aber wiederverwenden können wollen, ist dies eigentlich nie gegeben und Refactoring gehört zu einem professionellen Workflow immer dazu.

Nun habe ich diesen Artikel noch einige Male gelesen, verändert und hoffe er ist halbwegs verständlich. Sie werden aber bestimmt noch den einen oder anderen Fehler finden und stolpern vielleicht über manche Formulierung. Verstehen Sie, was gemeint ist… ?

Blog: Mehr als 250 Tausend im Sand

In einer Firma wurden rund 250 Tausend Euro investiert, um eine tolle neue Softwareidee zu verwirklichen. Einerseits wurde vor lauter Begeisterung bei den Investitionen nicht so genau auf die sinnvolle und ausbaufähige Umsetzung geachtet. Andererseits gab es auch nicht wirklich jemanden, der dies hätte beurteilen können. Nach 9 Monaten wurde dann leider klar, dass notwendige Änderungen nicht mehr effektiv möglich waren. Es wurde eine komplett neue Version des Softwareproduktes aufgesetzt und man hatte diesmal Unterstützung von Spezialisten, welche auf zukünftige Erweiterbarkeit und solide Entwicklungsarbeit drängten.

Alles verlief gut, die Entwicklung war deutlich günstiger als zuvor und man war noch einmal mit einem “blauen Auge” davon gekommen. Da es nun wieder voran ging, war man der Meinung sich von den Spezialisten trennen zu können. Es wurden junge, engagierte Mitarbeiter gefunden, die Lohnkosten sanken und man war zuversichtlich. Nur der Blick auf den Quellcode des Softwareprodukts hätte dem Fachmann verraten, dass die geschaffenen Grundlagen für Erweiterbarkeit und Wartbarkeit des Projekts mehr und mehr verloren gingen.

Engagement und Zuversicht alleine reichen nicht. Es braucht auch einige Erfahrung und viel Disziplin, um gemachte Fehler nicht zu wiederholen.

Szenarien wie das oben beschriebene sind beileibe kein Einzelfall. Seien Sie sich dessen bewusst und handeln sie entsprechend.

Blog: Einfach kompliziert

Auf der täglichen Suche nach Wissen, stolpert man im Internet über sehr viele Informationen. Es gilt hierbei, so schnell wie möglich die Spreu von Weizen zu trennen, um sich effektiv zu informieren. Darauf kommen wir bestimmt bald wieder zurück, aber vor einigen Tagen haben wir eine kleine, vermutlich unbewusste, aber vielsagende Bemerkung gefunden, welche wir doch mit Ihnen teilen möchten. Sinngemäß stand im WWW geschrieben:

“Dies zu erklären, ist eigentlich sehr einfach,
man könnte zwar ganze Bücher darüber schreiben,
aber ich beschränke mich auf das Wesentliche.”

Das trifft es doch sehr genau: Meist werden die einfachsten Dinge unglaublich verkompliziert. Wenn denn in Antworten überhaupt auf die ursprüngliche Frage eingegangen wird. Oft wurde diese vom Antwortenden nicht einmal verstanden oder falsch interpretiert. Menschen neigen eben dazu, viel zu sagen und oft leidet die Qualität der Aussagen darunter. Gesprächspartner schalten dann umso schneller ab und eine effektive Kommunikation ist schwer möglich.

Es gibt den Spruch (gerade für das Internet gültig): “Erst denken, dann noch einmal denken, und erst dann sprechen bzw. schreiben”. Wie wahr, wie wahr…

Auch wir bemühen uns diese Regel einzuhalten und haben damit manchmal noch unsere Probleme. Wir sind uns dessen aber bewusst und sie findet sich wieder im KISS Prinzip, welches definitiv zu unseren eigenen Richtlinien gehört.

Blog: Hohe Ansprüche, wenig Resultate

Mal wieder war es soweit. Ein Treffen zwischen Auftraggeber und Softwareentwickler stand an. Je zwei Teilnehmer beider Seiten sollten alle noch offenen Fragen klären.

Die Auftraggeber hatten extra einen wichtigen Termin verschoben und eineinhalb Stunden für das Treffen reserviert. Nach hinten war auch noch Luft, daher war es nicht ganz so schlimm, dass sie erst um 13:15 vor Ort eintrafen. Der vorige Termin hatte wieder einmal etwas länger gedauert.

Das Entwicklerteam wartete seit 13:00 Uhr im Besprechungsraum, nahm die Entschuldigung für die Verspätung dankend an und öffnete einige Dokumente, welche mittels Projektor an die Wand geworfen wurden. Es ging los, die Stimmung war gut.

Zwei Stunden später, die Situation ist hektisch, die Sicht der Auftraggeber:

Die beiden Entwickler waren knapp mit der Hälfte der im Vorfeld als E-Mail versendeten Punkte ihrer Liste fertig. “Punkte” war sowieso das falsche Wort – “Kapitel” oder “Abhandlungen” wäre treffender. Einer der Auftraggeber war gerade gegangen, sie hatten sich entschieden, dass den nächsten Termin auch einer alleine bewältigen könnte. “Wie lange soll das noch dauern?” dachte der Verbliebende. “Warum machen die Beiden es so kompliziert?” Er konnte sich kaum noch konzentrieren – die Flut von Detailfragen empfand er als unnötig und übertrieben. Gleichzeitig hatten er mit seinem Partner versucht noch zwei kleine Änderungen einzubringen, von denen eine mit sichtlichem Unmut akzeptiert wurde, die andere aber gleich als “jetzt nicht machbar” auf später verschoben wurde. Eigentlich gab es nur noch die eine unausgesprochene Frage:

“Warum kostet das alles soviel Zeit und Geld? Wie sollen wir so unsere Pläne verwirklichen?”

Das kommt Ihnen bekannt vor? Hier geht es zu Lösungsvorschlägen!