Grensing

Business Technology Consulting GmbH

Testen alleine reicht nicht

2017-03-31

"Testen ist eine sehr effektive Methode, das Vorhandensein von Fehlern zu zeigen - es ist aber hoffnungslos unzureichend, deren Abwesenheit nachzuweisen."

Diese schlaue Erkenntnis stammt aus dem Jahr 1972. Edsger Dijkstra - Pionier der theoretischen Informatik - beschrieb sie in einer Vorlesung, die noch heute lesenswert ist - denn das Problem ist auch in SAP-Projekten immer noch das gleiche, insbesondere wenn es nicht nur um Konfiguration, sondern vor allem um Softwareentwicklung geht.

Aber was ist die Alternative? Nicht mehr testen? Wohl kaum!

Ich möchte die Situation an einem Beispiel aufzeigen: die meisten Zusatzentwicklungen in SAP-Projekten funktionieren mehr oder weniger nach folgendem Muster:

keks=SAP->GibMirEinenKeks().

MachSchokogussDrauf(keks).

SAP->NimmDenKeksZurück(keks).

Diese Entwicklung testet man dann mit runden Keksen, mit eckigen, harten, weichen, man macht einen Negativtest ohne Keks und schließt die Entwicklung zufrieden ab.

Kurze Zeit nach Produktivsetzung die große Überraschung: Wurstbrot mit Schokoguss. Der Grund: fehlerhafte Stammdaten.

Funktioniert die Verarbeitung konsistent, ist das Ergebnis vielleicht so akzeptabel: Garbage-in, Garbage-Out.

Problematisch wird es aber, wenn entweder die Verarbeitung unkontrolliert abbricht oder ein falsches Ergebnis erzeugt, das so nicht bemerkt wird. Fehlerhafte Buchungen, Transaktionsabbrüche, eine mangelhafte Planung, verschwundene Aufträge - in der Folge unzufriedene Kunden und verlorener Umsatz: die Folgen können vielfältig und ernsthaft sein.

Wie kann man solche Situationen vermeiden?

Spezifiziert und entwickelt man zusätzliche Funktionalitäten, muss man sich der Tatsache bewusst sein, dass man nicht die vollständige Kontrolle über alle Abhängigkeiten hat. Man spricht in diesem Zusammenhang gerne von "schwarzen Schwänen." Schwäne sind üblicherweise weiß - etwas anderes erwartet man nicht bis man nach Australien kommt: da sind Schwäne schwarz. Hätten Sie das gewusst?

Ähnlich ist der Umgang mit Abhängigkeiten in fremden Programmcode: "Timeo Danaos et dona ferentes!" Fürchte die Danaer, selbst wenn sie Geschenke bringen.

Das beinhaltet:

  • Risikoanalyse der Abhängigkeiten während des gesamten Design- und Entwicklungsprozesses
  • Defensive Verwendung "verlockender" Angebote: nicht jede Tabelle enthält immer, was man glaubt; nur weil es einen Enhancement-Point gibt, heisst das noch lange nicht, dass man ihn auch nutzen sollte.
  • Festlegung des Systemverhaltens bei unerwartetem Input
  • Test der Abhängigkeiten und des Verhaltens der eigenen Entwicklung auch im Fehlerfall
  • Konstante und wiederholte Code-Reviews durch zusätzliche Personen
  • Anpassung der Unit-Tests nach Code-Review

SAP bietet Werkzeuge, die hier helfen, so zum Beispiel:

  • Das Unit-Test-Framework:
    • Test-Driven-Development beruht auf dem Ansatz, in einem ersten Schritt jegliche eigene Funktionalität komplett unabhängig von allen Abhängigkeiten (z.B. Datenbank, Standard-Funktionsaufrufe) testbar zu machen. Man modelliert seinen Code also so, dass zum Testen alle Abhängigkeiten durch Dummy-Logik ersetzt werden (Dependency-Injection). Das hat entscheidende Auswirkungen - auf den ersten Blick nicht immer nur positive - auf die Struktur des Quellcodes. Es erhöht die Komplexität manchmal erheblich und macht den Code nicht immer lesbarer, schafft aber ein langfristig robusteres Design.
    • Die Testfälle für die Unit-Tests werden programmiert. Und zwar von Anfang an zusammen mit der Entwicklung die getestet werden soll. Damit kann die Entwicklung jederzeit (auch nach Abschluss der Entwicklung) automatisiert getestet werden. Insbesondere in Hinblick auf spätere Änderungen ist dies von Vorteil, da so die Fehlerregression verhindert werden kann.
  • Coverage Analysis:
    • Tut ein Progammcode unterschiedliche Dinge, sollte er auf separate Methoden oder Klassen aufgeteilt werden. Diese im Grunde triviale Anforderung findet sich in den Programmierrichtlinien der meisten Unternehmen. Dennoch muss man immer wieder darauf hinweisen. Führt man nun automatisierte Unit-Tests durch, kann man mit Hilfe der Coverage Analysis feststellen, ob alle zu testenden Klassen und Methoden im Rahmen der Unit Tests abgedeckt wurden oder ob es ungetesteten Code gibt, der in den Tests nicht durchlaufen wurde.

Jede eigenprogrammierte Zeile ABAP-Code in einem produktiven SAP-System ist ein Unternehmensrisiko.

Viele Unternehmen sehen das anders: sie haben einerseits große individuelle Anforderungen, die für sie nicht durch Standardfunktionalität abdeckbar sind, auf der anderen Seite fehlt es an einem qualitätsbewussten Entwicklungsmanagement, so dass entweder in-House unkontrolliert "das-haben-wir-immer-schon-so-gemacht" gearbeitet wird oder aus Kosten- oder Imagegründen unzureichend ausgebildete aber billige Off-Shore-Entwickler herangezogen werden, ohne diese angemessen inhaltlich zu steuern.

Langfristig kann sich das rächen: die Fähigkeit, erfolgreich IT-Systeme zu nutzen ist Teil des globalen Unternehmenswettbewerbs.