xUnit

Testen von Programmen ist wichtig. Das wurde schon recht früh erkannt. Ich hab ja schon früher über Unit-Testing und Refactoring geschrieben. Jetzt les ich gerade das Buch „xUnit Test Patterns – Refactoring test code“ von Gerard Meszaros (ISBN-13: 978-0-13-149505-0). Dicker Schmöker mit knapp 890 Seiten. Ich werde hier jetzt ab und an ein paar Gedanken zu diesem Buch verfassen und wahrscheinlich auch Kapitelweise eine Zusammenfassung. Eigentlich dient das nur meinem Verständnis, aber vielleicht hat auch jemand anderes was davon 🙂

The Fragile Test Problem

In meinem Praxissemester bin ich über WinRunner gestolpert. An sich eine schöne Idee, einfach ein paar Mausbewegungen und Klicks aufzeichnen und schauen ob auch das rauskommt, was rauskommen sollte. Scheitert aber schon an diversen Sachen, z.B. wenn man die Sprache im Programm umstellt. Zwar sollte sowas nicht die Funktionalität eines Programmes verändern, aber wer weiss, Bugs sind überall. Meszaros kategorisiert das ganze (er nennt es „The Fragile Test Problem“) in vier Fallgruben aufgeteilt.

Behaviour Sensitivity

Wenn sich das Verhalten eines Systems ändert (weil sich z.b. die Anforderungen geändert haben), dann ist die Wahrscheinlichkeit, dass die Tests, die die geänderte Funktionalität prüfen, scheitern sehr gross (uff, was ein Satzbau). Das ist jetzt nichts spezielles für so Programme wie WinRunner, das ist immer so. Wenn ich bei einem Auto auf vier Reifen teste, die Requirements aber plötzlich ein Dreirad wollen, dann MUSS das schiefgehen. Richtig fies wird es erst, wenn wir uns auf die Funktionalität verlassen um das System in einen Status zu bringen, in dem wir einen Test ausführen.

Interface Sensitivity

Grundsätzlich ist das Testen einen Systems über die Benutzeroberfläche eine schlechte Idee. Jede minimale Änderung bringt jeden Test zum Scheitern. Und dies ist völlig unabhängig von der Benutzeroberfläche (GUIs wie QT oder GTK, CLI (Command Line Interfaces) oder Weboberflächen (Buzzword: Ajax, Web 2.0)).

Data Sensitivity

Alle Tests starten an einem Zeitpunkt, an dem bestimmte Konditionen gegeben sind. Irgendwelche Datenstrukturen sind vorhanden und werden genutzt. Solange man nich immensen Aufwand investiert um die Tests von diesen Daten unabhängig zu machen, ist es höchstwahrscheinlich das die Tests scheitern.

Context Sensitivity

Nachdem der Datenkontext schon wichtig ist, kommen natürlich noch andere externe EInflüsse dazu. Das können so simple Dinge wie die Uhrzeit sein (Sommer-/Winterzeitumstellung), aber auch Geräte wie Drucker oder Server.

All diese Abhängigkeiten machen das deterministische Wiederholen von Tests sehr, sehr schwierig. Natürlich gibt es viele Möglichkeiten diese Abhängigkeiten zu umgehen, aber egal welche Methode man nimmt, sie bleiben bestehen. Die xUnit-Familie stellt ein paar Muster zur Verfügung die uns einen grossen Grad an Kontrolle ermöglichen. Wir müssen nur noch lernen sie zu nutzen.

Dieses Testen wird übrigens „regression testing“ genannt. Regression bedeutet auf Deutsch „Rückwärtsbewegung“ und spiegelt das auch gut wieder. Wir haben ein fertiges Produkt und bewegen uns beim Testen von Vorne nach Hinten (Von der GUI zum Backend). Einen völlig anderen Ansatz spielt hier die testgetriebene Entwicklung (test-driven development), die das Prinzip umkehrt. Mittels dieser Methode wird eher das Verhalten von Software die noch geschrieben wird beschrieben, als die fertige Software rückwärts getestet.

Refactoring

Refaktorisierung, wie es auf Deutsch heißt, beschreibt eine Methode um Software „schöner“ zu machen. Jetzt fehlt nur noch die Definition von „schöner“ und dieser Post ist fertig 🙂

Das Problem von Improvisierungen ist, dass diese meist länger leben als sie sollten. Jeder hat bestimmt schonmal daheim ein Brett irgendwo untergelegt und wollte das „später“ dann mal ordentlich festschrauben, oder Ähnliches. Sowas gehört zur Kategorie: „Funktioniert, warum also ändern?!“.

Ähnlich ist das bei Software. Wenn ein armer Student als Praktikant plötzlich eine Software für einen Betrieb schreiben muss, dann kann man nur hoffen, dass er was von „Design, Analyse und Implementierung“ gehört hat, das Lasten- und Pflichtenhefte keine Fremdworte sind und dass Code der „ad hoc“ in den PC getrimmert wird, meist nicht das Gelbe vom Ei ist.  Aber selbst wenn man sich viele Gedanken gemacht hat und diese auch wunderbar mittels UML niedergeschrieben hat, jegliche Spezifikation sich aus den Fingern saugt und dann denkt das man „doch an alles gedacht hat“, so wird man doch meist von der Realität eingeholt und muss seine Software umstrukturieren. Hier greift dann die Refaktorisierung.

Natürlich gibt es auch andere Anwendungsgebiete, wie z.B. Anpassung einer Software an ein neues Betriebssystem, Erweiterung der Funktionalitäten oder Sonstiges, dies alles kann zur Refaktorisierung führen. Wichtigste Grundregel für die Faktorisierung ist aber:

Das System muss bereits laufen

Ohne ein laufendes System gibt es auch keine Refaktorisierung. Zweiter wichtiger Punkt ist die Tatsache dass die Funktionalität nicht geändert werden darf. Dies steht nicht im Widerspruch zur obigen Aussage „Erweiterung der Funktionalitäten“, da das Refactoring tatsächlich erstmal das „Aufräumen“ des Codes ist um dann im Nachhinein neue Features einzubauen.

Refaktorisieren ist relativ einfach. Man will eigentlich nur folgende Ziele erreichen (zitiert aus der Wikipedia):

  • Lesbarkeit
  • Übersichtlichkeit
  • Verständlichkeit
  • Erweiterbarkeit
  • Vermeidung von Redundanz
  • Testbarkeit

Wer schon einmal Klassen mit ein, zwei Funktionen gesehen hat, diese aber 170-180 Zeilen Code jeweils ausmachen, der weiss wie schwer es ist sich in diesen Wulst einzulesen. Warum also, wenn man den Code eh schon verstehen muss, den Code nicht auch gleich verständlicher machen?

Die Mittel der Refaktorisierung sind simpel und meist Schritt für Schritt zu erledigen. Einen schönen Katalog dazu hat Martin Fowler (Refactoring. Wie Sie das Design vorhandener Software verbessern. Addison-Wesley Verlag, ISBN 3-8273-1630-8) erstellt, dort wird über mehrere Kapitel genau erläutert wie man Schritt für Schritt Software „schöner“ macht. Ich empfehle jedem Softwaredesigner dieses Buch zumindest mal anzulesen. Ich werde es mir auch erst noch kaufen müssen, da ich bisher nur „auf der Arbeit“ einen Blick reinwerfen konnte.

Man sollte sich dringend in den Wikipedia-Artikel einlesen, auch wenn dieser recht schmalbrüstig ist. Dort sind aber gute (englische) Artikel verlinkt und ausserdem hat sich jemand die Mühe gemacht den oben erwähnten Katalog von Fowler online zu stellen.

3/14

Toller Titel, ist das Datum von heute, nur in der englischen Darstellungsweise. Heute ist ja auch der „Huldigt der Zahl PI“-Tag. Was es alles gibt.

Kommen wir zu der Zusammenfassung der letzten Tage, es ist eine Menge passiert, und meistens kam ich nicht dazu es hier zu veröffentlichen. Deswegen wird dies hiermit und sofort nachgeholt:

  • Inzwischen kann ich Boxen flashen. Was bedeutet: Ich kann den FPGA flashen und danach noch das Bios der Box. Näheres wird nicht erwähnt
  • Tank Gauging aus der Sicht des Marketings ist doch ziemlich interessant. Bisher kannte ich nur die Entwicklersicht, aber mal aus dem eigenen Teller auszusteigen um über einen fremden Tellerrand zu blicken hat durchaus Vorteile.
  • Postsendeanträge die nicht funktionieren sind lästig. Und da Nacharbeit teuer ist, hab ich 40 € und 6h Zeit investiert um ein Formular aus Karlsruhe zu besorgen das für mein Visum unentbehrlich ist. Ärgerlich wenn man Vorbereitungen trifft und diese absagen muss, weil eine „fremde“ Macht einem einen Strich durch die Rechnung macht
  • Refactoring ist ein interessantes Thema. Dazu werde ich noch einen eigenen Artikel schreiben.
  • Das Visum J-1 wurde inzwischen genehmigt (der Termin im US-Konsulat Frankfurt war heute) und wird mir im Laufe der nächsten Woche postalisch zugesandt. Ärgerlich ist es nur wenn man Stunden warten muss, weil sich andere Leute nicht an die Vorschriften halten und den kompletten Sicherheitscheck aufhalten, weil Sie mal nicht eine Stunde auf ihr Handy verzichten können. Auf jeden Fall kann der Flug jetzt gebucht werden.
  • Getoastetes Toast mit Schweinerückensteak und Champignonsahnesoße mit gemischtem italienischem Salat ist unglaublich lecker. Interessanterweise kann man mit Fleischkäse auch ein Cordon Bleu machen und das schmeckt dann sogar.