Test Driven Development - Specification by Example - Softwaredesign

The general principle of software quality is: Improving quality reduces development cost. You don’t have to choose between quality, cost and time- they all go hand in hand. Steve McConnell

Inhalt:

  • Workshopinhalte
  • Plattformen
  • Qualität - Ein Kostenfaktor
  • Test Driven Development
  • Specification by example
  • Refactoring, Objektorientiertes Design

Workshopinhalte

In diesem dreitägigen Workshop führen die Teilnehmer Übungen zum Thema Softwarequalität durch. Dazwischen wird in kurzen Vorträgen und Diskussionen auch die Theorie zu den Übungen vermittelt.

Der Workshop vermittelt einerseits Techniken, die die Teilnehmer direkt in ihrer täglichen Arbeit anwenden können, andererseits zielen manche der Übungen darauf ab, den Blick für wesentliche Aspekte der Softwarequalität zu schärfen. Die Teilnehmer lernen, gute und schlechte Tests zu erkennen, Risiko bei Änderungen durch immer kleinere Schritte zu minimieren, technisch “gute” Software zu schreiben und genau das zu liefern, was der Kunde wünscht.

An den drei Tagen werden folgende Inhalte vermittelt:

  • Tag 1: Test Driven Development, Unit Tests
  • Tag 2: Specification by Example, Agile Acceptance Testing, Akzeptanztestframeworks
  • Tag 3: Refactoring, Objektorientiertes Design, SOLID-Prinzipien

Plattformen

Ich habe diesen Workshop hauptsächlich für Java und .NET (C#) ausgelegt. Die Übungen, die in diesem Workshop durchgeführt werden, sind aber unabhängig von der verwendeten Programmiersprache. Manche der Übungen setzen allerdings eine objektorientierte Programmiersprache voraus. Außerdem werden zur Durchführung der Übungen noch einige Werkzeuge verwendet, z.B. ein Unit-Test-Framework oder ein Versionsverwaltungssystem. Diese Werkzeuge sind aber für alle gängigen Programmiersprachen verfügbar.

Es ist auch nicht unbedingt notwendig, dass der Workshop mit genau der selben Entwicklungsumgebung durchgeführt wird, mit der die Teilnehmer in der Praxis arbeiten. Die verwendeten Technologien sollten aber zumindest ähnlich sein, damit die Teilnehmer das Gelernte in ihren Projekten anwenden können. Wenn Sie nicht sicher sind, ob dieser Workshop in Ihrem Umfeld sinnvoll ist, dann kontaktieren Sie mich bitte.

Qualität - Ein Kostenfaktor

As the old expression goes, “time is money”. The corollary is that “money is time”. Steve McConnell

Ein dreitägiger Worshop kostet Ihre Firma Geld. Und zwar deutlich mehr, als das Honorar für den Vortragenden. Sie stellen außerdem noch die Räumlichkeiten und Hardware zur Verfügung und müssen die Workshopteilnehmer für drei Tage von Ihren Aufgaben freistellen. Da stellt sich die Frage:

Wie, beziehungsweise wie schnell, kann sich dieser Workshop rentieren?

Es gibt natürlich keine exakte, allgemeingültige Antwort auf diese Frage. Aber eine Abschätzung - zumindest der Größenordnung - ist möglich.

Softwareentwicklung ist teuer. Selbst ein relativ kleines Team kann, alle Kosten mit eingerechnet, einen fünf- bis sechsstelligen Betrag pro Monat kosten. Aber das wissen Sie ja. Das bedeutet aber, dass ein Prozent der Zeit des Teams mehrere hundert bis tausend Euro Wert sein kann.

Entwickler werden dafür bezahlt, Wert für den Kunden - und dadurch für das Unternehmen, in dem Sie arbeiten - zu schaffen (Das ist auch, nebenbei bemerkt, das, was wir am Liebsten machen). Aber: Kein Entwicklungsteam verbringt 100% seiner Zeit damit, Wert zu schaffen.

Viele Teams merken, dass die Produktivität mit der Zeit sinkt, also dass die Entwicklung langsamer voran geht - und damit mehr kostet - als noch vor einigen Jahren. Das liegt oft daran, dass die interne Qualität der Software schlechter wird und somit Änderungen immer aufwändiger und riskanter werden.

Imperative requirements are very easy to misunderstand. Gojko Adzic

Dazu kommt oft noch, dass nicht ganz genau verstanden wurde, was der Kunde eigentlich wollte. An jeder Kommunikationsschnittstelle gehen Informationen verloren. Und oft wissen die Kunden selbst nicht so genau, was sie benötigen. Auch für sie ist das aktuelle Projekt ein Lernprozess. So merkt man oft erst nach der Auslieferung, dass man zu wenig gemacht hat und nachbessern muss. Oder dass man zu viel - also überflüssige Funktionalität - geliefert hat. Was genauso schlimm ist, denn:

There is surely nothing quite so useless as doing with great efficiency what should not be done at all. Peter Drucker

Es wird auch in Zukunft kein Softwareentwicklungsteam schaffen, 100% seiner Zeit damit zu verbringen, Wert zu schaffen. Aber jede auch noch so kleine Verschiebung des Prozentsatzes bringt oder kostet Geld. Und das jeden Monat. Deswegen rentiert es sich, in eine Veränderung in die richtige Richtung zu investieren!

Test Driven Development

Writing test cases before the code takes the same amount of time as writing test cases after the code, but it shortens defect-detection-debug-correction cycles. Steve McConnell

Am ersten Tag des Workshops üben die Teilnehmer die “Testgetriebene Entwicklung” mit Hilfe von Unit Tests.

“Testgetriebene Entwicklung” (Test Driven Development, TDD) bedeutet, dass kein Code geschrieben wird, ohne dass dafür ein Test existiert. Das wird dadurch sichergestellt, dass man automatisierte Tests vor dem eigentlichen Code entwickelt. Da man die Tests sowieso entwickeln muss, ist dieses Vorgehen nicht teurer als die Tests im Nachhinein zu schreiben. Und es bringt einige Vorteile:

  • Es wird sichergestellt, dass ein testbares System entwickelt wird: Dadurch dass zuerst der automatisierte Test und erst danach das System entwickelt wird, ist das System zwangsläufig immer testbar.
  • Eine sehr hohe Testabdeckung wird sichergestellt: Funktionalität wird erst entwickelt, wenn dafür bereits ein automatisierter Test existiert.
  • Es wird nur die tatsächlich benötigte Funtkionalität implementiert: Nur für Funktionalität, die tatsächlich benötigt wird, werden Tests automatisiert. Und nur aufgrund von automatisierten Tests wird Funktionalität implementiert.
  • Die automatisierten Tests sind eine gute Dokumentation des tatsächlichen Systemverhaltens: Diese Dokumentation kann nie veraltet oder falsch sein, da sonst der Test nicht mehr laufen würde.
  • Zukünftige Änderungen sind weniger riskant: Bei jeder Änderung kann durch die bestehenden Tests sichergestellt werden, dass die bestehende Funktionalität erhalten bleibt.

Die Teilnehmer entwickeln eine kleine Beispielanwendung. Dabei automatisieren Sie die notwendigen Tests, bevor sie die eigentliche Funktionalität entwickeln. Sie lernen die Grundregeln von TDD (“red-green-refactor”) und was es bedeutet, diese wirklich rigoros einzuhalten. Die Teilnehmer lernen auch, wie sie das Risiko von Änderungen minimieren können, indem sie diese in kleineren Schritten durchführen.

Selbst wenn die Teilnehmer später, in der täglichen Arbeit, nicht immer “Testgetriebene Entwicklung” in Reinform anwenden, können sie von den Inhalten dieses Workshoptages profitieren:

Automatisierte Tests können, wenn sie richtig entwickelt werden, das Risiko von Änderungen minimieren, die tatsächliche Funktionalität dokumentieren, die Qualität des Systems erhöhen und dadurch die Entwicklungszeit verkürzen. Schlechte Tests können aber auch das Gegenteil bewirken: Sie verbessern die Qualität nicht maßgeblich, verringern die Lesbarkeit, machen Änderungen schwieriger und verlängern so die Entwicklungszeit. Deshalb lernen die Teilnehmer an diesem Tag, gute von schlechten Tests zu unterscheiden und können so die Vorteile von automatisierten Tests nutzen.

Specification By Example

Instead of abstract requirements, use realistic examples to demonstrate differences in possibilities. Gojko Adzic

Am zweiten Tag des Workshops lernen die Teilnehmer, wie mit Hilfe von realistischen Beispielen die Kommunikation im Projekt verbessert werden kann. Die Teilnehmer werden unterschiedliche Werkzeuge kennenlernen, mit denen Sie aus den Beispielen automatisierte Tests ableiten können.

Wie können Sie sicherstellen, dass Sie das richtige Produkt erzeugen? Genau die richtige Funktionalität implementieren - Weder zu viel, noch zu wenig? Diese Fragen sind von zentraler Bedeutung. Denn Funktionalität, die später nicht verwendet wird, ist doppelte Verschwendung! Es fallen nicht nur die Kosten für die Entwicklungszeit, in der kein Wert geschaffen wurde, an. Die überflüssige Funktionalität muss auch gewartet werden: Das System wird dadurch größer, komplizierter und eventuell Fehleranfälliger. Dadurch werden Weiterentwicklung und Änderungen schwieriger.

Oft wird versucht, diese Probleme mit möglichst detaillierten Anforderungsdokumenten in den Griff zu bekommen. Diese Dokumente enthalten meistens genaue Anweisungen, wie sich das System in bestimmten Situationen verhalten soll. Das Anforderungsdokument wird am Anfang des Projekts von allen Beteiligten unterschrieben, so will man sicherstellen, dass jeder das Dokument gelesen und verstanden hat. Dieser Ansatz bringt leider mehrere Probleme mit sich.

Je länger ein Anforderungsdokument wird, umso höher wird die Wahrscheinlichkeit, dass es in sich nicht mehr konsistent ist. Und selbst wenn alle Anforderungen widerspruchsfrei formuliert sind ist es sehr schwierig, sicherzustellen, dass jeder Beteiligte alles richtig verstanden hat. Denn jeder, der einen Text liest, interpretiert ihn ein Stück weit. Die Tatsache, dass alle Beteiligten unterschrieben haben, bringt am Ende auch nichts mehr: Man kann zwar einen “Schuldigen” finden, aber man hat trotzdem das falsche System entwickelt.

The most important information in a requirements document is the phone number of the author. Kent Beck

“Specification by example” versucht diese Probleme zu umgehen. Realistische Beispiele sind eine hervorragende Diskussionsgrundlage: Es ist deutlich einfacher, Widersprüche und Lücken in Beispielen zu finden als in langen Texten. Und während die Beispiele diskutiert werden zeigt sich, ob alle das selbe Verständnis von der geforderten Funktionalität haben.

Und es gibt einen weiteren, nicht zu unterschätzenden Vorteil: Aus den Beispielen können direkt automatisierte Testfälle abgeleitet werden. Somit kann, nachdem ein Teil des Systems entwickelt wurde, sofort überprüft werden, ob er alle Anforderungen erfüllt. Dadurch können alle am Projekt beteiligten jederzeit sehen, ob das System in der aktuellen Version alle Anforderungen erfüllt. Außerdem wird der Projektfortschritt sichtbar: Zu jeder Zeit ist ersichtlich, zu welchen Anforderungen es bereits realistische Beispiele gibt und welche dieser Beispiele bereits “laufen”.

Refactoring, Objektorientiertes Design

All successful software gets changed. Fred Brooks

Am dritten Tag des Workshops geht es um die interne Qualität von Software. Die Teilnehmer lernen einige Prinzipien objektorientierten Designs kennen und führen dazu Übungen durch. Außerdem lernen Sie anhand von Übungen, wann und wie Refactoring durchgeführt werden soll, damit die interne Qualität der Software auch über einen langen Entwicklungszeitraum hoch bleibt.

Wie wichtig ist die interne Qualität von Software überhaupt? Das primäre Ziel ist doch die Zufriedenheit der Anwender, nicht “schöner” Programmcode. Diese Aussage ist grundsätzlich richtig, aber etwas kurzsichtig gedacht. Denn: Die interne Qualität der Software bestimmt die zukünfitigen Entwicklungskosten!

Unter Zeitdruck passiert es oft, dass Abstriche bei der internen Qualität in Kauf genommen werden. Die Entwickler nehmen “Abkürzungen”, konzentrieren sich nicht mehr so sehr auf gutes Softwaredesign und hören auf, die Qualität ständig durch Refactoring zu verbessern. Und kurzfristig funktioniert das auch oft: Man wird mit der aktuellen Aufgabe schneller fertig.

Längerfristig macht sich aber eine Verschlechterung bemerkbar. Aufgaben, die früher schnell erledigt waren, sind “plötzlich” ungleich aufwändiger. Bei Fehlerbehebungen passiert es immer öfter, dass diese nicht auf Anhieb korrekt sind oder neue Fehler verursachen. Änderungen von bestehender Funktionalität werden immer schwieriger, die Neuentwicklung kommt fast zum Stillstand. Dadurch wird der Zeitdruck größer und man ist noch mehr geneigt, die interne Qualität zu vernachlässigen.

Genau deshalb ist es wichtig, immer auf ein gutes Softwaredesign zu achten. Die SOLID-Prinzipien helfen, gutes objektorientiertes Design zu erkennen und zu erstellen. In einer weiteren Übung lernen die Teilnehmer, verschiedene Probleme bei objektorientiertem Design zu erkennen und zu vermeiden.

Gutes Softwaredesign ist aber nicht etwas, das man einmal, am Projektanfang, macht und dann für den Rest des Projekts erledigt hat. Um ein gutes Design zu gewährleisten muss man ständig auf geänderte Rahmenbedingungen reagieren und neue Kundenwünsche berücksichtigen. Außerdem lernen die Entwickler während der Projektlaufzeit ständig dazu und müssen diese Erkenntnisse im Design berücksichtigen.

Deshalb ist Refactoring - also das Ändern der internen Programmstruktur ohne Änderung der Funktionalität - so wichtig. Damit stehen den Entwicklern Werkzeuge und Techniken zur Verfügung, mit denen sie die interne Qualität des Systems kontinuierlich verbessern können.

Interessiert?

Ich hoffe, ich konnte hiermit Ihr Interesse an diesem Workshop wecken. Wenn Sie diesen Workshop in Ihrem Betrieb durchführen möchten, dann kontaktieren Sie mich bitte, damit wir die Details besprechen können. Schreiben Sie mir doch eine E-Mail an business@davidtanzer.net oder rufen Sie mich an: +43-676-53 47 723