Was Softwareentwicklung vom Handwerk lernen könnte

Ich erinnere mich daran, wie im Dezember 2008 die ersten Gespräche bei 8thLight und Obtiva in Chicago geführt wurden, die im März zum Manifest des Software Craftsmanship führten. Viele der Ergebnisse bekam ich leider nur indirekt über die Software Craftsmanship Mailingliste mit. Dennoch erinnere ich mich an ein Gespräch, das ich zu der Zeit mit einem alten Freund hatte. Mein Freund ist Dachdecker und auch mehr als zwei Jahre später glaube ich noch fest daran, dass wir als Softwareentwickler – Tester wie Programmierer – viel von anderen Handwerksberufen lernen müssen.

Was Softwareentwicklung vom Handwerk lernen könnte weiterlesen

„Agil ist doch auch nur Wasserfall“

Im vergangenen Jahr hatte ich eine Diskussion mit einer Testexpertin über Agile Softwareentwicklung, Software Testen und Scrum. Wir waren beide auf der gleichen Testkonferenz, die primär auf eher traditionelles Tester ausgelegt war. Trotzdem war hier ein dominantes Thema Scrum, Agile Softwareentwicklung und wie testen denn mit diesem Agilen Kram überhaupt funktionieren kann.

In unserer Diskussion kam es schnell zu dem Punkt, bei dem es darum ging, was die Unterschiede zwischen Agil und Wasserfall sind. Besagte Testexpertin war der Meinung, dass Agil nichts anderes als ein Mini-Wasserfall sei. Am Anfang der Iteration werden Anforderungen aufgenommen, diese werden dann umgesetzt, und später am Ende der Iteration getestet. Damit lassen sich dann auch direkt alle bisherigen Methoden nicht nur vermitteln sondern direkt anwenden. Super. Problem gelöst. So geht also Agiles Testen.

Leider stimmt das nicht so ganz. Das Vorgehen löst in meinen Augen vor allem das Problem der traditionell eingestellten Trainer, die auf einmal auf den Agilen Wagen aufspringen sollen, aber birgt gerade im Zusammenspiel mit Agiler Entwicklung auch einige schmerzhafte Probleme. Welche das sind, und was man dagegen machen kann, will ich hier kurz aufzeigen.

„Agil ist doch auch nur Wasserfall“ weiterlesen

Wie testen Sie Software?

Ich bin der festen Überzeugung, dass irgendwas in den vergangenen 50 Jahren in der Softwareentwicklung schief gelaufen sein muss. Aus irgendeinem Grund existiert nach wie vor die Ansicht, dass wir auf eine bestimmte Art und Weise Software entwickeln sollten. Genau wie bei der Kindererziehung gibt es Kontrahenten für eine bestimmte Ausprägung und andere Kontrahenten für eine andere.

Über die Jahrzehnte haben sich gewissen Regeln und Erkenntnisse etabliert, die sich einem „Jungspunt“ wie mir nicht erschließen. Ein Beispiel ist meine Erfahrung, die ich zu Universitätszeiten gemacht habe, als ich in einem Kaufhaus gejobbt habe. Während meiner insgesamt 10 Jahre dort, habe ich insgesamt drei unterschiedliche Marktleiter und drei Abteilungsleiter erlebt. Alle hatten unterschiedliche Herangehensweisen.

Während einer Periode, als wir einen neuen Abteilungwleiter bekamen, drückte der damalige Chef eine Anordnung durch, dass Bestellungen nur noch vom Abteilungsleiter und dessen Stellvertretung gemacht werden durften. Die übrigen Mitarbeiter sollten „nur“ noch die gelieferte Ware packen, sowie die Reste verwalten.

Für das Trackensortiment hatten wir zwei Kataloge. Diese umfassten ca. 100 Seiten mit jeweils knapp 25 Artikel pro Seite. Das bedeutete für die Führungsebene, dass sie sich durch 2500 Produkte zweimal pro Woche durcharbeiten mußte. Der Faktor Mensch bei einer derartigen stupiden Tätigkeit – die zudem noch unter dem Termindruck, dass die Bestellung zu einem gewissen Zeitpunkt abgeschickt sein mußte, verschärft wurde – ist allerdings nicht zu unterschätzen. Bis dato hatte ich die Aufgabe, die rund 20 Seiten an alkoholfreien Getränken, Wein, Sekt und Spirituosen zu bestellen. Es brauchte einige Zeit der Einarbeitung, bis ich all die unterschiedlichen Ausprägungen an Weinen kannte, die in der Liste auftauchten. Es brauchte mindestens noch einmal so lange, bis ich wußte, welche Sorte gut lief und welche ich nur ab und an bestellen mußte.

Nun, welche Auswirkung hatte die Anordnung des Chefs? Mittelfristig wurde ich gefragt, ob ich nicht auch Konserven und anderen Produkte packen könne. Da ich eine der Ausnahmen war, die weiterhin bestellen durfte, nahm ich keine Veränderung in meinem Bereich der Getränke wahr. Aber was die Konserven anging, empfand ich zunehmend Unzufriedenheit beim Packen. Ein Beispiel waren Soßen zum Backen. Hier gab es eine Sorte Schokosauce in zwei Größen, klein und groß. Diese spezielle Sorte fiel mir beim Packen auf, da Woche für Woche die kleine Größe stets leer blieb, während die große Größe im Regal voll war, und drei weitere Einheiten kamen.

Es dauerte nicht lange, bis sich das LAger zunehmend mit Beständen füllte, die wir nicht verkauften. Der Faktor Mensch plus Zeitdruck führte dazu, dass viele Fehler unterliefen. Viel schlimmer, diejenigen, die die Waren räumten, und auch später die Reste nachräumten, wußten um die Probleme. Aber wegen des fehlenden Vertrauens gelang dieses Feedback auch nicht in die Führungsriege. Dadurch akkumulierten sich die Fehler immer mehr – nun, bis zu einem Kollaps, den ich aber nicht mehr erlebt habe.

Was können wir daraus lernen? Nun, zunächst einmal ist frühes Feedback wichtig. Je eher ich weiß, dass ich einen Fehler gemacht habe, desto eher kann ich daraus lernen. Wie Jerry Weinberg in „Becoming a Technical Leader“ erklärt, ist Lernen aus Fehlern ein Schritt, der zu Innovation führt. Zweitens schafft Vertrauen das Verhältnis, in dem ich gefahrlos Probleme kommuniziere. Vorwürfe sorgen dafür, dass ich mehr Energie meiner Arbeit darin stecke, diese Fehler zu verheimlichen. Energie, die ich andererseits vielleicht für meine Arbeit aufbringen würde. Und drittens habe ich daraus gelernt, dass die Trennung von Ausführendem und Verantwortlichen in einigen Situationen keinen Sinn macht. In einem Sportverein schreibt ja schließlich nicht der beste Trainer die Trainingspläne für alle Gruppen. Das würde gar keinen Sinn ergeben aus den zwei vorgenannten Gründen.

Nun, drei Jahre später fand ich mich in meinem ersten Job wider. Meine erste Reaktion war, warum in der Softwareentwicklung derartige Praktiken üblich waren. Tester und Programmierer arbeiten in unterschiedlichen Teams und Abteilungen, Analysten und Programmierer sind voneinander getrennt. Kunden und Entwickler sprechen nicht direkt miteinander. Wir nehmen uns dadurch wesentliches Feedback, das uns dabei helfen kann, bessere Software zu entwickeln.

Nun, damals hat mich das vielleicht ein wenig verwundert, und ich habe seitdem daran gearbeitet, dieses Silo-Denken abzuschaffen, wann immer ich es gesehen habe. Bis ich heute morgen das volle Ausmaß der Misere in der Softwareentwicklung wahrgenommen habe. Ich lese momentan ein Buch aus dem Jahr 1961. Der Name des Buchs ist „Computer Programming Fundamentals“ von Leeds und Weinberg. In diesem Buch wird das erste Mal über Softwaretesten geschrieben. Umso dramatischer empfand ich die folgenden Worte auf Seite 67:

In summary, the process of programming is not a fixed set of analyzable steps but rather a series of tentative trials, followed by careful testing of the results of those trials. Each step may be repeated several times before its particular problems are all solves. Sometimes it is necessary to attempt the succeeding steps in order to verify a particular step. […] It occurs far too frequently that a program is completed, only to reveal that the problem it solves is not really the problem of interest. Similarly, if the analysis is incorrect, the answers from any resulting program will not be solutions to the problem.

Das war vor ziemlich genau fünfzig Jahren. Die Autoren sprechen in dem Buch darüber, wie Assembler funktionieren, dass sie numerische Codes aus Assemblerbefehlen generieren, und worauf man aufpassen muss, wenn man diese händisch übersetzt. Wie kommt es, dass wir fünfzig Jahre später, nach weiteren Abstraktionsebenen wie höheren Programmiersprachen, prozeduraler Programmierung und objekt-orientierter Programmierung immer noch der Meinung sind, dass diese Mechanismen nach wie vor funktionieren können? Haben sich unsere Probleme in den letzten fünfzig Jahren denn gar nicht gewandelt?

Ich denke, wir sollten – insbesondere als Tester – kritisch gegenüber Meinungen anderer sein. Wie kommt es dann, dass wir nicht kritisch gegenüber der Methoden sind, die wir tagtäglich einsetzen sollen, nur weil sie ein Trainer uns mal beigebracht hat? Ich denke, wir sollten jede Methoden viel häufiger hinterfragen, und darüber reflektieren, wie sie uns bei der Lösung unseres derzeitigen Problems hilft. Natürlich sollten wir dafür erst einmal wissen, welches Problem wir überhaupt haben.

Und ich hoffe, dass jemand genau diese Sichtweise ebenfalls in Frage stellen wird.

Vier Denkrichtungen im Software Testen

Auf Entaggle hat mich vor einiger Zeit James Lyndsay mit einem Tag versehen: „has a problem with authority“ – hat ein Problem mit Autorität. Er versah dieses Kennzeichen mit dem Kommentar „healthily so“ – und das ist auch gut so.

Was veranlasst ihn dazu, mir diese Kennzeichnung zu verpassen? Die Antwort liefert ein Buch aus dem Jahr 2002: Lessons Learned in Software Testing. In diesem Buch erklären Cem Kaner, James Bach und Bret Pettichord in rund 300 Lektionen, welche Erfahrungen sie im Software Testen in den unterschiedlichsten Projekten gemacht haben. Mit ihren zusammen mehr als 60 Jahren Erfahrung (damals) sicherlich eine gute Quelle.

Doch aus der Arbeit für dieses Buch wuchs mehr. Der Untertitel lautet „A context-driven approach“ – ein kontextabhängiger Ansatz. Während sie ihr Wissen aufschrieben formulierten diese drei einen Testansatz, den in meinen Augen viel zu wenige Tester kennen. Ihnen war nämlich aufgefallen, dass es gröbere Kategorien dafür gibt, wie einige Tester, die sie getroffen haben, denken, und warum diese unterschiedlichen Denkrichtungen sich nicht untereinander verstehen, bzw. verschiedener Meinung sind. Hieraus entstanden die vier Denkrichtungen im Software Testen.

Über diese vier Denkrichtungen streiten sich die seitdem die Anhänger – oder auch nicht Anhänger. Ich persönlich glaube, dass es sinnvoll ist, sich darüber im Klaren zu sein, woher unsere Tätigkeit kommt, welche Schritte sie auf dem Weg in das Jetzt durchlebt hat, und unter welchen Voraussetzungen zu anderen Zeiten heute merkwürdig erscheinende Entscheidungen getroffen wurden. Die Vier Denkrichtungen helfen dabei.

Analytisches Testen

In den frühen Jahren ging es bei Fehlern in Software vor allem um Probleme, die auftraten, dadurch dass bei der Übersetzung der Software von der Assemblersprache (ADD EAX) in die Maschinensprache (0402 03219) Fehler mit Registern und Befehlen auftraten. Durch den Übersetzungsprozess konnten sich derlei Fehler einschleichen.

Außerdem konnte es sein, dass nach dem Anpassen von Software (zum Beispiel nach einem Bugfix) die Register neu geordnet werden mussten. Dann wurde ein Zwischenergebnis auf einmal durch ein weiteres Ergebnis überschrieben. Oder ein Zwischenergebnis war auf einmal ein ganz anderes Ergebnis.

Diese Fehler lassen sich analytisch finden, indem man den Quellcode immer und immer wieder analysiert und auf Fehler prüft. Sog. „Clerks“ machten in dieser Zeit diese Art von Tätigkeiten. Und die Softwareindustrie hatte eine Menge davon. Kein Wunder. Menschliche Arbeitskraft war damals im Verhältnis zu Maschinenkosten weitaus günstiger zu bekommen.

Standards

Während der Software Engineering Revolution entstand historisch dann ein Ansatz, der auf einen standardisierten Prozess legte. In den 70ern wurde viel Wert auf die Wiederholbarkeit von Ergebnissen gesetzt. Zu der damaligen Zeit glaubte man, dass Standards genau dabei helfen. Wenn alle das gleiche tun, dann kommt schließlich immer das gleiche am Ende raus – und – man verzeihe mir diesen kätzerischen Kommentar – die Fehler sind ebenfalls immer die gleichen.

Zur damaligen Zeit ging es vor allem darum, dass Tester aus den Bereichen kamen, die später durch Software weg rationalisiert werden sollten. Die damaligen Tester waren als Experten in der Domäne der Software, die sie testen sollten. Hier kam es vor allem darauf an, den Fortschritt hin zu fertigen Software zu messen – gerade im Wasserfall- und V-Modell zu der Zeit eine durchaus gängige Denkweise.

Aber es ging auch darum, dass Tester möglichst wenig Fähigkeiten benötigen sollten. Die Kosteneffizienz der frühen Jahre war das Ziel. Dafür sollten jetzt Studenten Tests durchführen. Einige davon blieben später bei dieser Tätigkeit.

Der Nachteil hierbei ist natürlich, dass Standards nichts über Fähigkeiten einzelner Entwickler aussagen, und ein wiederholbarer Prozess nicht unbedingt wiederholbare Ergebnisse liefert. Aus diesem Grund musste die nächste Denkrichtung her.

Qualität, Qualität, Qualität

Das Problem war klar: die Tester müssen mehr Macht bekommen. Ab sofort geht nur noch Software in Richtung Produktion, wenn diese durch die Tester frei gegeben wurde. Tester sind ab sofort eine Schranke. Die Software geht erst raus, wenn die Tester das ok dazu geben.

Das Problem mit dieser Herangehensweise ist nach meiner Erfahrung, dass dieser Mechanismus nie funktionieren konnte. Wenn man Testern mit standardisierten Fähigkeiten die Macht gibt, über Go oder No-Go der Software zu entscheiden, dann werden diese zwangsläufig bei kritischen Entscheidungen von der nächst höheren Instanz einfach übergangen. Schließlich können Tester ja nicht alle Faktoren, die hinter der Entscheidung stehen, kennen. Richtig?

Absolut richtig. Aber dann kann ich mir diese ganze Zeremoniell mit den Freigaben auch von vornherein sparen. Aber das bringt mich zu dem anderen Problem zurück: Unsere Software hat bei der Auslieferung keine gute Qualität. Wie bekommen wir die denn dann?

Kontextabhängiges Testen

Nun, die drei zuvor genannten Personen – Kaner, Bach und Pettichord – kamen zu dem Schluss, dass manche Praktiken in manchen Projekten Sinn machen, in anderen wiederum nicht. Abhängig davon, in welchem Projekt man sich befindet, macht es beispielsweise Sinn, den IEEE Standard für Testdokumentation zu verwenden – Atomkraftwerke, ferngesteuerte Militärwaffen, Autosteuerung – oder gar leichtgewichtige Testdokumentation wie Tests als Spezifikation – Agile Softwareentwicklung einer Webanwendung – zu verwenden. Das gleiche gilt für Methoden wie Testfallerstellung durch Entscheidungstabellen, Grenzwerte (redaktionelle Anmerkung: zu einer Zahl +1 und -1 zu rechnen ist keine Form der Analyse) oder auch paarweises Testen.

Hieraus wuchs die Kontxtabhängig Denkrichtung. Diese setzt vor allem auf die Zusammenarbeit zwischen Projektbeteiligten, aber auch darauf, dass es keine beste Möglichkeit – sog. „best practices“ – gibt. Es gibt höchstens Praktiken, die in einem gewissen Zusammenhang – dessen Kontext – Sinn gemacht haben – einmal. Ein Ansatz, der vor allem Wert auf die kritischen Denkfähigkeiten eines Testers setzt.

Diese Denkweise macht also deutlich, dass ein gesundes Misstrauen einen guten Tester auszeichnet. Und genau das gilt auch für mein Problem mit sog. Autoritäten. Nur weil es sie gibt, muss ich ihnen nicht trauen. Ganz im Gegenteil: durch kritisches Hinterfragen finde ich heraus, wann eine Denkweise einer sog. oder auch selbst-ernannten (woran merkt man den Unterschied?) Autorität Sinn ergibt, wann nicht und welche dieser Situationen ich bereits erlebt habe, bzw. in welchen Situationen ich dieses gezielt nicht ausprobieren wollte.

Wenn also das nächste Mal ein Berater Ihre Frage mit „kommt drauf beantwortet“, bedeutet das nichts anderes, als „ich verstehe Ihre Situation noch nicht völlig.“ Bei guten Beratern wird diese Antwort allerdings auch mit „Hier sind ein paar der Situationen, die ich bisher erlebt habe. Welche macht in Ihrer Situation am meisten Sinn?“ zu einem Gesamtbild ergänzt.