Strategien und Techniken zur Fehlerprävention
Irren ist menschlich, und Fehler passieren – insbesondere in der Softwareentwicklung. Qualitätssicherung soll dafür sorgen, dass die Software trotzdem fehlerarm zum Kunden geht. Aber vielleicht geht es ja besser? Können Entwickler Vorsorge betreiben, um das Entstehen von Fehlern zu verhindern?
![Strategien und Techniken zur Fehlerprävention](https://heise.cloudimg.io/width/610/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/1/9/0/4/9/7/5/fehler-25dccc8627c8ff59.jpeg)
- Joachim Hofer
Die klassische Qualitätssicherung ist oft hauptsächlich auf das Finden von Fehlern ausgerichtet, die bereits passiert sind. Im Idealfall findet sie die Fehler durch Einsatz mannigfaltiger Techniken wie statischer Codeanalyse, Reviews und Tests bereits so früh wie möglich nach dem Entstehungszeitpunkt. Aber wenn man Fehler von vornherein vermeiden will, muss man sich als Erstes fragen, wie Fehler überhaupt zustande kommen.
Zur Klärung dieser Frage lohnt es sich, zunächst zu untersuchen, wodurch allgemein menschliche Fehler verursacht werden. Hierfür ist die Kognitionspsychologie eine Fundgrube: Die wesentliche Erkenntnis ist, dass Fehler entstehen, wenn der Mensch kognitiv überlastet ist. Ein typisches Beispiel dafür ist die Überlastung des Arbeitsgedächtnisses: Dieses kann nur etwa fünf bis neun Dinge gleichzeitig parat halten [1]. Das ist sehr wenig, sodass so gut wie alle Entwickler bei der täglichen Arbeit schnell an diese Grenze stoßen wird. Beispielsweise wenn sie sich bei Codeänderungen merken müssen, wo genau sie schon etwas geändert haben, an welchen Stellen welche Änderungen noch ausstehen und was jeweils die zugehörigen Anforderungen sind, während sie gleichzeitig noch die E-Mails im Auge behalten wollen oder gar zwischendurch von hilfesuchenden Kollegen unterbrochen werden. Ganz zu schweigen davon, dass sie vielleicht nicht immer alle Tastenkürzel der Entwicklungsumgebung, alle Syntaxkonstrukte der Programmiersprache und die Semantik der verwendeten Bibliotheken in- und auswendig kennen.
Ein Ansatz für das Verhindern von Fehlern ist also, die Komplexität der Arbeitsumgebung zu senken. Dazu gehört neben dem eigentlich bearbeiteten Programmcode das Umfeld, in dem er entsteht, wie am obigen Beispiel zu sehen.
Komplexität im Arbeitsumfeld lässt sich oft durch organisatorische Maßnahmen senken: Weiterbildungen können dafür sorgen, kognitive Last vom Arbeits- ins Langzeitgedächtnis zu verlagern, wenn es um das Programmierhandwerk geht (Syntax, Bedienung der Entwicklungsumgebung, Tastaturkürzel, Schnittstellen zu Fremdbibliotheken oder -frameworks). Prozesse können helfen, unnötige Störungen von außen zu reduzieren. Zeitmanagement-Techniken wie Pomodoro [a] oder "Getting Things Done" [2] unterstützen dabei, Ablenkungen und unnötigen kognitiven Ballast loszuwerden, der nicht die aktuell bearbeitete Aufgabe betrifft. Das simple Beenden des Mailprogramms während der Arbeit beseitigt einen der größten Störfaktoren. Und nicht zuletzt hat die Gestaltung des Arbeitsplatzes große Auswirkungen darauf, ob man fokussiert arbeiten kann.
Zwiefache Komplexität
Eine das Arbeitsumfeld betreffende Ergänzung zum alleinigen Senken der kognitiven Last wäre, die eigene Leistungs-/Konzentrationsfähigkeit zu steigern. Dafür gibt es vor allem ein erprobtes Mittel ohne Nebenwirkungen: das hinreichende Entspannen in der Freizeit und das Vermeiden exzessiver Überstunden. Das oberste Ziel dabei ist immer: den Kopf für die eigentliche Arbeit frei zu haben. So profan das auch klingen mag, es hilft bereits dabei, Fehler zu vermeiden. Wenn das Arbeitsumfeld erst einmal stimmt, bleibt die für Entwickler spannendere Frage übrig: Welche Techniken gibt es in der Softwareentwicklung, die helfen, die Komplexität des entwickelten Codes zu reduzieren? Die Frage stellt sich zwar nur, wenn sich Entwickler überhaupt für die Qualität der erstellten Software verantwortlich fühlen, statt das der QS-Abteilung zu überlassen.
An der Stelle ist aber glücklicherweise in letzter Zeit ein starkes Umdenken in Gang gekommen, gerade auch in Zusammenhang mit dem Einzug agiler Methoden in die Softwareentwicklung. Entsprechend ist es weit verbreitete Praxis, dass Entwickler Tests schreiben, bevor sie den getesteten Code dazu implementieren (bekannt als "Test-Driven Development" [3]; TDD). Tatsächlich kann dieses helfen, Fehler zu vermeiden. Denn durch TDD werden Entwickler gezwungen, die Sicht der Tester einzunehmen, bevor sie die Funktion "konstruktiv" betrachten, um sie zu implementieren.
Das verhindert eine andere Fehlerquelle, die beim nachträglichen Testen durch Entwickler immer eine Gefahr ist: den Bestätigungsfehler (auch "Confirmation Bias"). Er entsteht durch die menschliche Neigung, die Realität mit zuvor gestellten eigenen Erwartungen möglichst in Einklang zu bringen. Im Fall der klassischen Softwareentwicklung mit nachgelagertem Testen bedeutet das: Die Entwickler implementieren zunächst die Funktion, wobei sie ihre eigenen Erwartungen umsetzen und festigen, und danach testen sie die Implementierung gegen genau diese Erwartungen. Der Confirmation Bias sorgt so beim Testen dafür, dass sie unbewusst gar keine Fehler finden wollen.
Der klassische nachgelagerte Softwaretest kennt diese Fehlerquelle natürlich auch, weswegen dort zwischen Testern und Entwicklern meist strikt getrennt wird. Man sollte sich aber bewusst machen, dass dabei leicht über das Ziel hinaus geschossen wird, wenn von einem speziellen Tester-"Mindset" die Rede ist, das Entwickler gar nicht haben können. Entsprechend in Testmethoden ausgebildete Entwickler sind durchaus in der Lage, kritisch zu testen – solange er es im Sinne von TDD tut, bevor sie sich an die Implementierung setzen.
So unabdingbar das Testen für die Softwarequalität ist, und so sinnvoll TDD in dem Zusammenhang ist, bleibt jedoch ein Nachteil: Man findet Fehler immer erst nach deren Entstehen. Es ist in diesem Sinne also von der Zielsetzung her immer noch keine echte Vorsorge.