Das Internet und die Freiheit

Ich habe mich bisher in diesem Blog zu politischen Themen zurückgehalten. Aber bei der aktuellen Diskussion um Internetzensur mache ich mir ernsthaft Sorgen um unsere Volksvertreter. Zuerst soll das BKA ohne richterlichen Beschluss einzelne Seiten sperren können – begründet mit dem Kampf gegen Kinderschänder. Der Kampf ist sinnvoll aber das Mittel… Der Widerstand des Volkes formierte sich – anscheinend mit Erfolg: z.B. die Online-Petition mit über 100.000 Unterzeichnern.

Spiegel-Online veröffentlichte einen interessanten Artikel zu dem Thema, der das Thema und den digital organisierten Widerstand thematisiert.

Jetzt holt die Regierung zum erneuten Schlag aus. Ein schöner Artikel dazu findet sich hier (bei den Kommentaren sind auch ein paar coole dabei).

In China sind heute jede Menge Internetadressen nicht aufrufbar (z.B. die von Twitter). Bewegen sich unsere Volksvertreter in eine ähnliche Richtung?

Always use the front door

Es ist jetzt schon eine ganze Weile her, dass ich mit meine it-agile-Kollegen Sebastian Sanitz und Bernd Schiffer in einem Grails-Projekt zusammengearbeitet habe. In diesem Projekt hatten wir uns entschieden, Oberflächentests mit Canoo Webtest zu schreiben.

Bereits nach kurzer Zeit stießen wir auf Probleme. Wie kann man mit Canoo Webtest direkt auf fachliche Funktionen oder die Datenbank zugreifen, um zu prüfen, dass die Daten korrekt erzeugt wurden?

Bernd vertrat die Ansicht, dass unsere Schwierigkeiten keine Schwäche von Canoo Webtest seien, sondern ein Feature. Es sei keine gute Idee, direkt auf die Fachlogik oder die Datenbank zuzugreifen. Stattdessen solle man die Tests nur gegen die Oberfläche schreiben. Er zitierte dazu ein Prinzip namens „Always use the front door“. Der Zugriff auf Fachlogik oder DB wäre quasi die Hintertür und die Oberläche die Haustür. Sebastian und ich hatten von diesem Prinzip noch nie etwas gehört, aber Bernd hat standhaft behauptet, das sei ein etabliertes Prinzip. (Spätere Internet-Recherchen zeigten, dass man mit dem Suchbegriff in Google nur einen Blogeintrag von Bernd findet.)

Wie auch immer. Wir einigten uns darauf, es mit „Always use the front door“ zu versuchen. Das ging eine ganze Weile gut. Dann trat das nächste Problem auf. Wir mussten die Zeit im System nicht nur manipulieren, sondern auch einfrieren, um deterministische Tests zu bekommen. Bei Unittests ist klar, dass man sich dafür einen Zeitgeber baut mit einem passenden Interface. So kann man den Zeitgeber dann mocken und hat damit volle Kontrolle über die Zeit. Aber dieses Vorgehen war ja jetzt verboten. Wir durften nicht einfach eine Funktion im Systen aufrufen, um einen Zeitgeber durch einen Mock zu ersetzen.

Die Lösung für das Problem kam mind. mir etwas eigenartig vor. Wir haben einen TimeController programmiert, so dass man über eine REST-Schnittstelle die Zeit manipulieren und einfrieren kann. Wir haben das System also mit einer Benutzungsschnittstelle versehen, die man fachlich gar nicht braucht. Und natürlich hatten wir den Zusatzaufwand, den Controller so zu entwickeln, dass er im Produktivbetrieb nicht ansprechbar ist – wir wollten ja nicht, dass irgendein Schlauberger die Zeit des Systems manipuliert oder einfriert.

Gut, das funktionierte. Wir konnten den Test formulieren und haben uns an das Haustür-Prinzip gehalten. Aber war das vernünftig? In diesem Fall würde ich die Frage mit „ja“ beantworten. Zum einen war der Aufwand für den zusätzlichen Controller in Grails auch nicht größer als hätten wir einen Unittest-artigen Mock programmiert. Und außerdem war der Controller auch beim manuellen Testen des Systems sehr nützlich – klassisch hätte jemand auf dem Server die Systemzeit umgesetzt – und wahrscheinlich vergessen, sie nach dem Test wieder korrekt einzustellen.

Danach kam ein größeres Problem auf uns zu. Unser System verschickt E-Mails. Das kann man mit Canoo Webtest ganz elegant testen. Dummerweise dauert es vom Versand bis zum Empfang einer E-Mails eine undefinierte Zeitspanne – ist halt asynchron. Also haben wir den Test nach Versand der E-Mail warten lassen. Und jedesmal, wenn der Test wegen Timeout fehlschlug, haben wir die Zeitspanne erhöht. Dadurch wurden die Testlaufzeiten immer länger und das grundsätzliche Problem blieb. Wenn die Webtests fehlschlugen, konnten wir auf Anhieb nie sicher sein, ob wir einen Bug hatten oder nur die Zeitspanne für das Warten auf E-Mails zu kurz war. Diese Situation haben wir erstaunlich lange ertragen. Letztlich machte Sebastian dann soviel Druck, dass wir nochmal nachdachten. Wir hatten also eine Situation, die wir bei Unittests niemals akzeptiert hätten. Also haben wir uns gefragt, ob wir die Situation bei den Webtests nicht verbessern können. Die erste Idee war – wieder mal -, das Abrücken vom Haustür-Prinzip. Wenn wir direkt Funktionen des Systems aufrufen würden, könnten wir das Problem Unittest-like lösen: Einfach einen Mock für das E-Mail-System reinklemmen und fertig.

Und tatsächlich funktioniert dieser Ansatz auch dann, wenn man das Haustür-Prinzip befolgen möchte. Dazu ändern wir zunächst unsere Perspekive auf das System: Wir zerteilen unser System in zwei Systeme, das Kernsystem für den eigentlichen Zweck und eines für das E-Mail-Versenden. Das Kernsystem ist vollständig synchron und daher auch automatisiert gut testbar. Das E-Mail-System ist asynchron und schwer automatisiert testbar. Dafür ist es so klein, dass die so entstehende Testlücke risikoarm wird.

Diese Unterteilung kann man ganz unterschiedlich durchführen. Eine Möglichkeit besteht darin, dass das Kernsystem die E-Mails nicht direkt versendet, sondern die E-Mails erstmal in eine Tabelle schreibt. Ein E-Mail-Versende-Job des E-Mail-Systems fragt diese Tabelle regelmäßig ab und versendet die E-Mails. Wurde die E-Mail erfolgreich versendet, wird der entsprechende Datensatz markiert. Für den Test existiert ein spezieller Controller, der den Inhalt dieser E-Mail-Tabelle anzeigt. Der Webtest arbeitet mit dieser Tabelle und wird daher wieder deterministisch und schnell. Und auch in diesem Fall bringt uns diese Herangehensweise einen positiven Seiteneffekt. Man kann den Controller zum Monitoring der Anwendung verwenden und so im Produktivbetrieb besser kontrollieren, was im System passiert.

Eine andere (von Sebastian vorgeschlagene) Variante wäre, Kernsystem und E-Mail-System nicht über die DB zu koppeln, sondern z.B. über REST-Aufrufe. Dann könnte man für den Test ein Dummy-E-Mail-System konfigurieren, dass die REST-Aufrufe entgegennimmt und protokolliert und der Test würde dieses Protokoll prüfen. Und dann könnte man sogar soweit gehen, dass man hier einen generischen Protokoll-Service einsetzt, der einfach alle REST-Aufrufe protokolliert und (wie Unittest-Mocks) vordefinierte Antworten liefert. Das hört sich echt cool an. Das sollte man jemand bauen. Sebastian?

Insgesamt kann man also sagen: Wir wissen nicht wirklich, woher das Prinzip stammt und ob Bernd es sich selbst ausgedacht hat, aber es funktioniert auch für Akzeptanztests sehr gut.

Umbau meiner Website, Schritt 1

Ob sich der Umstieg von WordPress auf Blogger gelohnt hat, kann ich noch nicht sagen. Ich bin allerdings nicht deshalb umgestiegen, weil ich mich gelangweilt habe und zuviel Zeit mein Eigen nennen durfte. Der Auslöser war ein Buch. Ich habe begonnen „Designing the Moment“ von Hoekman zu lesen. Über die ersten paar Seiten bin ich noch nicht hinaus, aber die hatten es für mich schon in sich.

Das Buch beginnt mit der Frage, was man mit der Web-Site eigentlich erreichen will. Und das hatte ich mir noch nie richtig überlegt. Ursprünglich habe ich mit dem Bloggen angefangen, weil alle das gemacht haben und dann wurde es zu einer Gewohnheit. Aber warum nehme ich es auf mich, immer wieder Artikel zu schreiben und Kommentare zu beantworten? Ich habe darüber nachgedacht und bin zu einem Ergebnis gekommen:

Ich möchte Werbung für mich als Person und meine Arbeit machen, um interessante Aufträge für mich zu generieren.

Und wenn ich das ernst nehme, reicht ein Blog nicht aus. Dann müssen die Leser leicht bestimmte Informationen über mich bekommen können, wie z.B. meine E-Mail-Adresse, weitere Kontaktdaten, meine Tätigkeitsschwerpunkte, meine Projekterfahrungen etc. Und dafür benötige ich neben dem Blog statische Seiten. Und so bin ich zu WordPress gekommen, auch wenn das mit Blogger auch irgendwie geht (mit Google-Sites).

Die erste Lektion aus dem Buch habe ich also umgesetzt. Ich habe mir Gedanken gemacht, was ich primär mit meiner Seite will und bin an die Umsetzung gegangen. Inzwischen gibt es Seiten mit meinen Kontaktdaten und mit meinem Profil.

Ich habe vor, synchron zu meinem Lesefortschritt im Buch meine Website umzubauen. An den Statistiken müsste ich erkennen können, ob es etwas bringt.

Ubuntu für No-Details-Charaktere: Schritt 14 (Bestandsaufnahme)

Vor ziemlich genau 2 Monaten bin ich auf Ubuntu umgestiegen. Seinerzeit hatte ich meinen ersten Blogeintrag dazu beendet mit:

Jetzt werde ich versuchen, schrittweise immer mehr Anteile meiner Arbeit am Rechner unter Ubuntu zu erledigen. Mal sehen, wie weit ich komme. Ich werde weiter berichten.

Wie man an meinen Blog-Postings sehen kann, bin ich mit meinem Vorhaben ziemlich weit gekommen. Ich arbeite fast ausschließlich mit Ubuntu und fahre Windows für Spezialfälle ca. alle 2-3 Wochen einmal hoch. Und diese Spezialfälle werden weniger.

Unausrottbar scheint das Problem mit Power-Point zu sein – wenn man mit einem Windows-Benutzer  zusammen eine Präsentation erstellt. Open-Office kann Power-Point lesen und schreiben. Leider klappt das nicht zu 100%. Kleinigkeiten sind gerne mal kaputt – das liegt möglicherweise gar nicht an Open-Office, sondern daran, dass die Font-Metrics unter Windows und Ubuntu unterschiedlich sind und daher Umbrüche anders gesetzt werden. Falls da jemand eine Lösung weiß, wäre ich sehr dankbar.

Stories schneiden

Bernd Schiffer hat in seinem Blog ausführlich und gut beschrieben, warum und wie man Stories zerschneiden sollte, um sie klein zu kriegen.
Dazu habe ich noch eine Ergänzung, die Straßenmetapher beim Dimensional Planning. Bei diesem Ansatz unterscheidet man die „Schönheit von Stories“ und verwendet eine Straßenmetapher (Diese Art des Kleinschneidens ist in Bernds Ausführungen bereits implizit enthalten.) Stories können in vier Ausführungen realisiert werden:

  • Feldweg: minimal billige Lösung, die irgendwie funktioniert. Beispiel: Ich will eine Rechnung drucken. Dazu setze ich SQL direkt in der mySQL-Konsole ab. Die ermittelten Daten übertrage ich von Hand in MS-Word und drucke die Rechnung von dort aus.
  • Kopfsteinpflaster-Straße: sehr einfache Lösung, die schon Vereinfachung/Mehrnutzen bringt. Beispiel: Die Rechnung wird automatisch gedruckt, enthält aber nur die gesetzlich vorgeschriebenen Daten wie Kunde, Gesamtbetrag und MWSt.
  • Alphaltierte Straße: gute Standardlösung. Beispiel: Die Rechnung bekommt noch die Positionen dazu.
  • Autobahn: Top-Lösung. Beispiel: Der Kunde kann seine Rechnung personalisieren.

Diese Metapher kann man zum einen gut dazu verwenden, um mit dem Product Owner auszuhandeln, wieviel überhaupt notwendig ist. Das kann die Abschätzung des Product Backlogs vereinfachen.
Und dann kann man diese Ausbaustufen auch zeitlich betrachten (auch innerhalb eines Sprints). Zuerst baut man den Feldweg und erweitert ihn dann in Richtung Kopfsteinpflaster-Straße etc.

Pull und Kanban – über die Entwicklung hinaus

Das Pull-Prinzip stammt aus dem Lean-Production und ist ein (mehr oder weniger expliziter Aspekt) agiler Softwareentwicklung. Die Idee ist, dass man nicht Arbeit in eine Ressource (z.B. Team) hineindrückt (push), sondern die Ressource sich selbst neue Arbeit holt (pull), wenn sie keine mehr hat. So wird Überlastung der Ressource vermieden.

In Scrum holt sich das Team im Sprint-Planning soviel Arbeit ab, wie es meint, im Sprint realisieren zu können – auch wenn der Product-Owner gerne mehr realisiert haben möchte. Er darf nicht mehr Arbeit in die Sprint drücken. Das Team wendet also Pull an.

Wenn man das Pull-Prinzip weiterdenkt, muss man mind. die Prozesse nach der Entwicklung mit einbeziehen (upstream processes). Faktisch findet in vielen Organisationen nach dem Sprint noch abschließende Qualitätssicherung und Überführung in den Betrieb statt. Dort sollte man natürlich auch nach dem Pull-Prinzip verfahren. Das Team drückt also nicht mit einer festen Live-Deadline die Ergebnisse des Sprints in die Qualitätssicherung und den Betrieb. Stattdessen holen sich Qualitätssicherung und Betrieb ihre Arbeiten, wenn ihre Auslastung es zulässt.

Wie setzt man das konkret um? Ganz Basic-Lean gedacht würde sich der Product Owner an das letzte Element der Wertschöpfungskette wenden und seinen Feature-Wunsch äußern, z.B. „Ich möchte, dass ich die Kontakthistorie von Kunden einsehen kann.“ Diesen Auftrag würde er auf einen Zettel schreiben und an den Betrieb geben.

Der Betrieb würde daraus einen (Sub-)Auftragszettel an die Qualitätssicherung formulieren: „Ich möchte eine qualitätsgesicherte Funktionalität haben, die den Anwendern erlaubt, die Kontakthistorie von Kunden einzusehen. Außerdem muss die Funktionalität geclustert auf einem Tomcat mit mySQL betrieben werden können.“

Die Qualitätssicherung macht daraus einen Auftragszettel an das Entwicklungsteam: „Ich möchte eine Funktionalität haben, die den Anwendern erlaubt, die Kontakthistorie von Kunden einzusehen. Außerdem muss die Funktionalität geclustert auf einem Tomcat mit mySQL betrieben werden können. Die ganze Funktionalität muss soweit möglich mit FIT akzeptanzgetestet sein und es muss Beschreibungen geben, was noch manuell zu testen ist.“

Dann beginnt das Entwicklungsteam, diesen Arbeitsauftrag abzuarbeiten. Wenn es fertig ist, liefert es die Systemfunktion an die Qualitätssicherung zusammen mit dem zugehörigen Auftragszettel. Die Qualitätssicherung verfährt entsprechend an den Betrieb und dieser an den Kunden.

Der ganze Arbeitsfluss wird also über Auftragszettel gesteuert. Diese Auftragszettel heißen im Lean-Production Kanban.

Mit den Auftragszetteln wie beschrieben in der Softwareentwicklung vorzugehen, ist i.d.R. unnötig teuer. Es wird zu viele Missverständnisse geben. Viel besser ist das persönliche Gespräch. Also wendet sich der Product Owner direkt an das Team und erläuert, was er benötigt. Was uns dann der ganze Kanban-Ausflug bringt? Bei diesem Gespräch (Sprint Planning) müssen Qualitätssicherung und Betrieb einbezogen werden. Man faltet den Prozess mit den Auftragszetteln zusammen, um schneller zu sein. Die Beteiligten bleiben aber dieselben!

Wann auf TDD verzichten?

Gibt es eigentlich Situationen, in denen man nicht testgetrieben arbeiten sollte? Mir fallen drei Stück ein.

  1. Ich exploriere, ob und wie etwas funktioniert (z.B. eine neue Technologie).
  2. Es gibt ein definitives Datum in der nahen Zukunft, ab dem das System nicht mehr weiterentwickelt und irgendwann stillgelegt wird.
  3. Wir haben eine Startup-Situation, in der wir eine Idee sehr schnell am Markt testen wollen.

Zu Punkt 1: Exploration
Charakteristisch ist, dass der Code ständig massiv umgebaut wird. Jedesmal Tests anpassen zu müssen, kann sehr aufwändig sein. Mitunter ist man schneller, wenn man dann ganz auf das Testen verzichtet. Man muss dann eben auch nur den Mumm haben, nach der Exploration den ganzen ungetesteten Code wegzuwerfen und vernünftig neu zu schreiben.
Natürlich gibt es bei der Exploration auch Situationen, in denen Tests helfen. Das ist vor allem dann der Fall, wenn man ein neues API ausprobiert. Dann ist der Unit- oder FIT-Test häufig ein angenehm leichtgewichtiger Client für den Test.

Zu Punkt 2: Stilllegung
Wenn das System nicht mehr weiterentwickelt wird, gibt es auch keinen Grund, Aufwand in die Renovierung des Legacy-Codes zu stecken. Allerdings muss man sich auch sicher sein, dass die Stilllegung auch kommt. Viel zu häufig wird es nicht präziser als „das System läuft bestimmt nicht mehr so lange“. Was von solchen Prognosen zu halten ist, wissen wir spätestens nach dem Jahr-2000-Problem: Die ursprünglichen Entwickler der Systeme haben auch gedacht, dass ihre Systeme bestimmt nicht so lange laufen. Man muss sich also wirklich, wirklich sicher sein!

Zu Punkt 3: Startup
Bei Startups ist charakteristisch, dass ein schneller Markteintritt essenziell ist. Wenn es gut läuft, verdient man nach dem Markteintritt soviel Geld, dass man davon das System neu und vernünftig getestet nochmal schreiben kann. Wenn man also schneller an dem Markt kommt, wenn man die Tests weglässt, ist das ein valides Argument, auf TDD zu verzichten.
Natürlich gibt es irgendwann eine kritische Masse, ab der man bei der Entwicklung mit Tests schneller ist als ohne. Aber wo liegt diese Grenze? Ich hätte sie aus dem Bauch heraus bei 20-50 Personentagen Programmieraufwand verortet.
Also prüfen wir mal diese Hypothese. Ich habe Clipboard2Web vor diesem Hintergrund ohne Tests programmiert. Und bis zum ersten Release hat sich das nach meiner Einschätzung auch gelohnt. Jetzt ist aber der Zeitpunkt gekommen, ab dem ich mit TDD schneller vorankomme. Wieviel Aufwand habe ich bis zu diesem Punkt investiert? 12 Personenstunden! Ergo: Vergesst das mit dem Weglassen der Tests in Startup-Situationen. Es lohnt sich nicht.