Was ist eigentlich Software Testing?

7. Januar 2013 von Hans Hartmann, Objentis Software Integration 0

Foto: iStockphoto

Von Zeit zu Zeit passieren wirklich spektakuläre Software-Pannen. Eine Flughafeneröffnung gerät zur Blamage, weil das Gepäckssystem versagt (Heathrow Terminal 5). Mehr als 17 Millionen Kundenkonten sind bei den Konzerntöchtern RBS, NatWest und Ulster Bank zeitweise den ganzen Tag über nicht abrufbar, weil die Installation einer Software für die Kundenverwaltung das Gesamtsystem korrumpiert hat. Eine der größten österreichischen Banken lässt es sich 21 Mio. Euro kosten, um ihre Kunden mit Gutscheinen zu besänftigen, weil die neue Online-Banking-Software tagelang nicht funktioniert.

Wo steckt das Problem?

Was unterscheidet das Heute vom Gestern?

Was muss man testen?

Wer sollte testen?

Weiter auf der nächsten Seite: Wo steckt das Problem?

Hans Hartmann leitet seit 2007 als Test Director die technischen Tests bei Objentis. Foto: Privat

Wo steckt das Problem?

Eine grobe Überschlagsrechnung ergibt, dass man mit einhundert bestens bezahlten Testern ein Jahr lang testen könnte, um einen entsprechenden Ausfall zu vermeiden. Es ist anzunehmen, dass man einen weitaus geringeren Testaufwand benötigt. Es ist weiter anzunehmen, dass im betreffenden Fall die Folgeschäden noch viel größer ausfallen werden, als diese einmalige Gutscheinaktion bereits ausmacht. Es ist weiterhin auch anzunehmen, dass die Software sehr wohl getestet wurde. Banken und Versicherungen kennen das Risiko von nicht getesteter Software. Wie kann dann ein derartiges Versagen zustande kommen? Kann es überhaupt eine Garantie geben, dass sich solche Vorfälle nicht weiter häufen werden? Bei Unwettern und Naturkatastrophen kann man die Schuld (auch wenn sie noch nicht eindeutig herleitbar ist) auf globale Erwärmung und Umweltverschmutzung schieben. Für den Anstieg an Software-Fehlern gibt es keine unmittelbare Erklärung. Getestet wurde doch immer schon und das hat früher auch gut funktioniert. Warum sollten die bewährten Rezepte auf einmal versagen?

Programme sind komplexer geworden

Der Grund ist einfach: Die Programme sind “komplexer” geworden. Das könnte bedeuten, dass man mehr Testaufwand treiben muss. Um wie viel mehr? Nehmen wir das Jahr 2000 und das Jahr 2010. In dieser Zeit haben sich bewegte Datenvolumina um den Faktor 50.000 vermehrt. Wenn wir im Jahr 2000  an einem Programm zwei Wochen getestet haben, müssten wir mit der gleichen Mannschaft im Jahr 2010 hunderttausend Wochen testen, also circa zweitausend Jahre. So lässt sich das also nicht rechnen.

Schließlich ist Software heute effizienter geworden, die Entwicklungswerkzeuge lassen viele Fehler schon vor der erstmaligen Kompilation erkennen und modernes objektorientiertes Software-Design ermöglicht es, sauber und weniger fehleranfällig zu programmieren.

Welchen Faktor sollen wir also annehmen, um mit den erhöhten Datenvolumina Schritt zu halten? Vergessen wir einen Faktor von 50.000! Geben wir uns mit 50 zufrieden. Dann müssten wir nur 100 Wochen testen. Doch das bedeutet immerhin noch zwei Jahre. So viel Zeit wird für Testen nicht eingeplant, so viel kann gar nicht eingeplant werden. Bis jetzt sind wir aber von einem sehr primitiven Ansatz ausgegangen. Wir haben nur Größen und Mengen verglichen. Das müsste noch nicht unbedingt bedeuten, dass die Software wirklich komplexer geworden ist. Schließlich war es eines der Hauptargumente für die Verwendung eines Computers, dass es egal sei, ob er Berechnungen fünfmal oder fünftausendmal durchführen müsste.

Die Zuverlässigkeit bleibe – im Unterschied zu der des Menschen – dieselbe. Wir erinnern uns vielleicht an die Entwicklung von mobiler Telefonie. C-Netz-Telefone in großen schweren Koffern, die schon viel handlicheren D-Netz-Telefone und die heute verfügbaren Smartphones mit mehr Rechenleistung als Mainframes vor 20 Jahren. Abgesehen von den reinen technischen Daten überlegen wir uns, was wir heute mit einem Smartphone alles tun können. Vor allem überlegen wir uns, mit wie vielen anderen Systemen wir – sogar gleichzeitig – verbunden sein können. Es ist die Anzahl dieser möglichen Verbindungen, welche den entsprechenden Komplexitätszuwachs ausmachen.

Kurz zusammengefasst können wir den Ausdruck Komplexität auch mit folgendem Satz beschreiben: Wir müssen mit dem Problem fertig werden, dass Quantität eine veränderte Qualität bedingt. Es ist auch etwas ganz anderes, für zweihundert Personen als für zwei zu kochen.

Weiter auf der nächsten Seite: Gestern und heute

Was unterscheidet das Heute vom Gestern?

Vor vierzig Jahren war das Programmieren noch nicht so ganz erfunden, zumindest nicht im heutigen Sinn. Wenn wir heute jemanden dazu bringen wollten, in Assembler oder COBOL zu programmieren, würde er uns groß ansehen und möglicherweise auch begründen können, dass die Verwendung der Sprachen heute nicht mehr zielführend sei. Allerdings mussten die Programmierer von kaufmännischen Systemen im Wesentlichen darauf zurückgreifen. Manche verwendeten auch FORTRAN, was speziell bei der Erzeugung von ansprechend formatierten Ausdrucken ein gewisses Problem darstellte. Es geht allerdings nicht um die Programmiersprachen. Man kann auch heute noch in den erwähnten Sprachen gute Programme schreiben.

Es geht um die Anzahl der Lösungsmöglichkeiten, die sich für ein gestelltes Problem anboten. Manchmal konnte man froh sein, wenn es eine mögliche Bewältigungsart für ein programmtechnisches Problem gab. Systemanalytiker untersuchten, wie man den Fluss “Problem”, man stelle sich einen Bach von mindestens zehn Meter breite vor, ohne Zuhilfenahme eines Bootes und ohne nass zu werden, überqueren könnte. Man suchte Stellen, an denen sich große Steine im Fluss befanden, über die man an die andere Seite hinüber balancieren konnte. Heute gibt es für ein Problem zehn verschiedene Lösungsmöglichkeiten, die ein Software-Architekt danach untersucht, ob sie verschiedenen Qualitätsanforderungen entsprechen. Für den Fluss “Problem” wurden bereits zehn verschiedene Brücken gebaut. Wenn man entscheidet, die “Autobahnbrücke” verwenden zu wollen, muss man sich allenfalls noch um die Zubringer kümmern. Auch wenn für uns ein einfacher Holzsteg gereicht hätte, verwenden wir jetzt die Autobahnbrücke und bauen an jeder Seite zwei Zubringer, was uns insgesamt mehr Aufwand kostet als es die Errichtung des Holzsteges getan hätte. Wir befürworten diese Lösung mit dem Hinweis, dass wir nicht die einzigen sind, die über den Fluss wollen.

Die Änderungen, die sich in der Software für uns ergeben, lassen sich an zwei Beispielen deutlich machen:

Beispiel 1: Ein technisches Gerät, ein sogenannter Frequenzanalysator von einer der angesehensten Firmen benötigte für die Fast-Fourier-Transformation weniger als acht Tausend Byte. (Die Zahlen sind bewusst ausgeschrieben. Sie erinnern sich vielleicht, dass einer der Computer, welche die Apollo-11-Kapsel zum Mond steuerten, von einem Programm ähnlicher Größe gesteuert wurde.) Von einem Mitarbeiter jener Firma erfuhr ich, dass heute der benötigte Programmteil ungefähr zwei Millionen Byte benötigt. Das passiert nicht ohne Grund. Wenn an den achttausend Byte vielleicht ein Jahr lang gebastelt wurde, lässt sich die gleiche Aufgabenstellung heute in zwei Wochen lösen. Die Aufwände haben sich verlagert und es ist ökonomischer, rasch entwickeln zu können statt auf Ressourcenminimierung zu achten.

Beispiel 2: Hätte es vor vierzig Jahren einen Fahrkartenautomaten gegeben, mit dem man einen Eisenbahnfahrschein hätte lösen können, hätte man einen Ablauf von Fragen vorgefunden, die man der Reihe nach beantworten hätte müssen:

– Von wo wollen Sie wegfahren?

– Wohin wollen Sie fahren?

– Wie alt sind Sie?

– Haben Sie Ermäßigungsanspruch?

– Welche Klasse wollen Sie benützen? usw.

Wären Sie im Zuge der Beantwortung darauf gekommen, dass Sie nicht genügend Geld haben, – oder vielleicht nicht genügend Münzen(!) – hätten Sie den Vorgang abgebrochen und wären beim nächsten Mal wieder den ganzen Fragenkatalog durchgegangen. Auf den heutigen Ticket-Automaten der ÖBB (ähnlich auch in den Automaten der DB) finden Sie die Fragen etwas versteckter in Form von Feldern, die sie antippen. Sie geben nicht mehr das Alter ein sondern tippen auf Normalfahrschein oder Halbpreis oder andere Angebote. Sie müssen nicht mehr den Zielort ausbuchstabieren. Sie tippen den Anfangsbuchstaben und die Auswahl möglicher Zielorte wird bereits eingeschränkt.

Die Anordnung der Eingabefelder deutet an, dass man die Eingabe in beliebiger Reihenfolge machen kann. Das ist aber bis zum heutigen Tag nicht möglich. Haben Sie nämlich den Ermäßigungsanspruch eingegeben, können Sie anschließend nicht mehr auf die 1. Klasse “hochrüsten”. Es kommt allerdings nicht die Fehlermeldung: “Klasse 1 muss eingegeben werden, bevor eine Ermäßigung angewählt wird” sondern eine Meldung, die etwa besagt, dass “auf dieser Strecke die 1. Klasse im Zug nachgekauft werden muss”.

Ein Gesamtablauf lässt sich nicht mehr durchtesten

Abgesehen davon, dass von diesem Fehler nicht die Welt untergeht, kann man erkennen, dass die Programmierer eine ursprünglich lineare, einfache Eingabesequenz auf ein graphisches Eingabesystem umgesetzt haben und hierbei einige Fehler passiert sind. Ganz bestimmt sind aber nicht alle Eingabemöglichkeiten getestet worden, sonst hätte man die fehlerhafte Fehlermeldung korrigieren können.

Nehmen wir an, der Automat muss fünf verschiedene Eingaben verarbeiten und die Reihenfolge dieser Eingaben ist beliebig, dann gibt es 120 verschiedene Kombinationen, wie die Eingaben getätigt werden können. Wir können wohl einsehen, dass nicht jede mögliche Variante ausgetestet worden ist.

Wir haben das letztere Beispiel ganz bewusst gewählt. Es zeigt einen typischen Fall, der aber hinsichtlich der Fehlermöglichkeiten noch überschaubar bleibt. Wenn Sie heute ihr mobiles Telefon zur Hand nehmen, meinen Sie, dass hier nur lauter einfache Abläufe betroffen sind. Die Anzahl der Beeinflussungen, welche zwischen den verfügbaren Abläufen auftreten, übersteigt das vorige Beispiel um mehrere Größenordnungen.

Wir fassen zusammen: Während früher einzelne Funktionalitäten für sich allein getestet werden konnten und dann ein(!) Gesamtablauf getestet werden musste, haben wir heute die Interaktionen der einzelnen Funktionalitäten zu testen. Die Anzahl dieser Interaktionen ist aber unmittelbar von der Anzahl der möglichen Ablaufkombinationen abhängig. Diese Anzahl ist sehr groß und kann sich leicht im siebenstelligen Bereich bewegen. Wir können nicht alle Interaktionen testen.

Weiter auf der nächsten Seite: Was man testen muss

Was muss man testen?

Wir können nicht alles testen, doch was müssen wir unbedingt testen? Im Jahr 2000 hörten wir bei einer Konferenz in Deutschland, dass die Anzahl der möglichen Zustände in einem Programm der Größe von Excel-4 ungefähr 10^80 wäre. Das ist eine unvorstellbare Zahl, die noch unglaublicher wird, wenn die Anzahl der unterscheidbaren Teilchen im Weltall auf 10^160 – damals im Jahr 2000 von Steven Hawkings – geschätzt wurde. Beide Zahlen wagen wir zu bezweifeln. Doch selbst wenn wir auf ein Prozent reduzieren, oder auf ein Prozent von einem Prozent, dann haben wir es noch immer mit 10^66 zu tun. Auch diese Zahl ist nicht vorstellbar. Wir können nicht jeden möglichen Fall testen, der auftreten kann. (Das war übrigens die Verteidigung jener Bank, welche die Kunden mit Gutscheinen zu trösten versuchte.)

Entwickler können auch testen

Die Aussage, dass wir nicht alles testen können, kann aber im vorliegenden Problemfall nicht verwendet werden. Denn gemessen an dem, was wir nicht testen können, fallen die wenigen Testfälle, die uns einfallen, auch nicht mehr ins Gewicht. Dann verzichten wir überhaupt auf den Test. Diesen Vorschlag haben wir gerade heute von einem Qualitätsmanager der Bank of America gelesen. Er hat allerdings nicht gemeint, dass man nicht testen solle. Er meinte lediglich, dass doch die Entwickler genauso gut testen könnten wie dedizierte Tester. Diese Meinung mutet aus dem Mund eines Amerikaners seltsam an, wenn man weiß, dass es beim Volkssport American Football eine Aufteilung der Spieler in die unterschiedlichsten Rollen gibt, wobei nicht nur generisch die Angreifer von der Defensive unterschieden werden, sondern außerdem noch „special teams“ für spezielle Aufgaben vorgesehen sind.

Wenn jemand ein Programm testen soll, ist eine der grundlegenden Aufgaben die Festlegung, welche Testfälle herangezogen werden. Viele Firmen verwenden Entwickler, um die Arbeit von anderen Entwicklern zu testen. Oder sie verlegen den Test in den Fachbereich, weil dessen Personen die einzigen sind, welche die Anforderungen, die an das Programm gestellt werden, wirklich kennen.

Weiter auf der nächsten Seite: Wie gehen Entwickler oder der Fachbereich vor?

Wie gehen Entwickler vor?

Entwickler testen in der Regel, ob die Anforderungen erfüllt sind. Wenn eine bestimmte Anforderung durchgeführt werden kann und das richtige Resultat geliefert wird, ist der Testfall in Ordnung. Wenn die Testfälle so gewählt worden sind, dass jede Anforderung mindestens einen Testfall zugeordnet bekommt, ist das Programm in Ordnung, sobald alle Testfälle ein gutes Resultat liefern.

Das klingt wie eine gesunde Strategie. Wir überlassen es unseren Leserinnen, an dieser Stelle eine kurze Pause einzulegen und nachzudenken, was an der geschilderten Überlegung falsch sein könnte. Die Lösung wird etwas später nachgeliefert.

Wie geht der Fachbereich vor?

Prinzipiell richtet er sich nicht an den allgemeinen Anforderungen aus sondern an den Anforderungen, die für sein eigenes Geschäft wichtig sind. Arbeiten mehrere Personen des Fachbereichs am Test mit, so werden wir vielleicht sogar eine Abdeckung aller Anforderungen bekommen. Der Fachbereich wird seine Testfälle noch zusätzlich verfeinern. Er besitzt nämlich Erfahrung, was in der Vergangenheit alles schief gegangen ist. Er kennt bestimmte Kunden, Kundenvorgänge, Konten, Polizzen, Produktzusammenstellungen, welche in der Vergangenheit immer wieder Probleme aufgeworfen haben. In der Fachsprache heißt das „erfahrungsbasierter Test“. Dieser stellt bereits eine Verbesserung des Testfahrens dar, wenn er mit den Testverfahren des Entwicklers verglichen wird.

Unser blinder Fleck beim Testen ist etwas kleiner geworden, doch er ist noch immer vorhanden. Welche Fehler übersieht sowohl der Entwickler als der „Business Domain Specialist“?

Wir haben bisher nicht geschrieben, wie die Anforderungen zustande gekommen sind. Wir haben keine Aussagen getroffen, ob die Anforderungen bereits überprüft worden sind. Ob man sie „getestet“ hat, ob ein Review durchgeführt worden ist. Sehr häufig fehlt z.B. der Abgleich zwischen Lastenheft und Pflichtenheft.

Wie haben die Ersteller des Pflichtenhefts das Lastenheft verstanden?

Bei der Erstellung von Anforderungen treffen wir ein systemisches Problem an: Der Anforderer kann sich nicht das Verhalten der letztlich programmierten Software vorstellen. Das ist eine verzeihbare Schwäche, die in der menschlichen Natur liegt. Viele Fehlhandlungen des Menschen sind dadurch begründet, dass er sich über bestimmte Konsequenzen keine Vorstellung machen kann. Es hat sehr lange gedauert, bis in Europa die Gurtenpflicht akzeptiert wurde. (Obwohl die Vorteile schon lange vorher in Amerika nachgewiesen werden konnten) Man kann sich doch abstützen war eine der häufigsten Ausreden. Action-Filme unterstützen derartige Fehlvorstellungen durch aufregende Szenen, die in Wirklichkeit sämtliche physikalischen Gesetze verletzen würden.

Es kommt nicht so selten vor, dass ein Vertreter des Fachbereichs ein Programmverhalten als unmöglich bezeichnet, dass er in der Anforderungsphase selbst hineinreklamiert hat. Letztendlich hat er aber recht, wenn er im fertigen Produkt den Fehler reklamiert. In seiner ursprünglichen Vorstellung sah das eben noch ganz anders aus.

Viel häufiger passiert es allerdings, dass Anforderungen fehlen. Das geschieht deswegen, weil sie als selbstverständlich angesehen werden. Fehlende Anforderungen werden weder vom Entwickler noch vom Fachbereich erkannt. Der Entwickler hat das Fehlen der Anforderung irgendwann während des Programmierens festgestellt und eine Annahme getroffen. Oft hat er sich rückversichert und jemanden vom Fachbereich gefragt, ob die Annahme denn auch richtig wäre. Der Fachbereich denkt kurz nach und die Annahme erscheint als plausibel. Diese Annahme wirkt wie eine versteckte Anforderung, die allerdings nie nachgelesen oder validiert werden kann. Zurückkommend auf unser Beispiel vom Fahrkartenautomaten wird jetzt der Anwender in die Annahme eingebaut. Der Anwender muss doch wissen, dass er die Knöpfe in der Reihenfolge von oben nach unten betätigen muss. Das muss er wissen, obwohl er sonst sehr wohl eine unterschiedliche Reihenfolge einschlagen kann. Das Programm sagt ihm nicht, dass er zuerst den obersten Knopf drücken muss, wenn er in der zweiten Zeile anfängt zu drücken.

Weiter auf der nächsten Seite: Was einen guten Tester ausmacht

Wer sollte testen?

Der Tester – oder sagen wir zu ihm „der professionelle Tester“ – kennt weder die Annahme des Entwicklers noch die Bestätigung des Fachbereichs. Er versucht sich in die Rolle des Anwenders hineinzudenken. Hier beginnt nun der kreative Denkprozess des Testers. Er versucht Eingaben des Anwenders zu antizipieren, die falsch sind. Wir wollen hier ein anderes Beispiel heranziehen, welches heutzutage nicht mehr so große Probleme bereitet, aber in der Vergangenheit schon zu großen Zeitverlusten geführt hat.

Bei der Eingabe eines Passwortes ist in der Regel auf Groß/Kleinschreibung zu achten. In den meisten Fällen wird bei der Eingabe eines fehlerhaften Passwortes heute darauf hingewiesen. Heute wird auch noch ein zusätzlicher Hinweis gegeben: Achten Sie darauf, dass die CAPS-LOCK-Taste (Feststelltaste) nicht gedrückt ist. Ob sie gedrückt ist, zeigt in der Regel ein kleines Lämpchen an. Ohne den Hinweis ist der Anwender aber viel zu irritiert. Vielleicht hat er sich ja wirklich vertippt. Und so versucht er die Eingabe ein zweites und drittes Mal und landet plötzlich in einer neuen Anzeige: Ihr Passwort wurde gesperrt. Setzen Sie sich mit ihrem Systemadministrator in Verbindung.

Wenn Sie schon ein paar Jahre mit Computerarbeit vertraut sind, wird Ihnen dieses Szenario nicht fremd vorkommen. Dieses Szenario passiert aber in abgewandelter Form auch heute noch in jeder Software. Ihre Eingabe verletzt eine Geschäftsregel (Business rule) von der Sie nichts wissen. Gute Programme geben Ihnen in diesem Fall eine entsprechende Fehler-und-Hilfemeldung. Wenn die Geschäftsregel aber in Wirklichkeit auf einer verborgenen Annahme beruht, hat der Entwickler keine solche Fehler-und-Hilfemeldung vorgesehen. Das Programm wird wie ein störrischer Esel verweigern. Das ist noch die bessere Reaktion. Es kann auch passieren, dass die fehlerhafte Eingabe akzeptiert wird und zu einem späteren Zeitpunkt in einer Datenbank abgespeichert wird. Beim nächsten Start des Programmes kommen Sie auf einmal nicht mehr an Ihre Daten heran, weil der fehlerhafte Eintrag die Datenbank korrumpiert hat, worauf Ihre Abfrage nicht mehr ordnungsgemäß durchgeführt werden kann.

Windows-NT hatte 65.000 Fehler

Zu Beginn dieses Kapitels wollten wir die Menge der Testfälle und getestete Zustände reduzieren. Jetzt sieht es so aus, als kämen noch viel mehr Testfälle dazu, als die Entwickler und der Fachbereich testen würden. Wir wollen hier noch eine Zwischenüberlegung einstreuen. Für das Betriebssystem Windows-NT (das in Vergleich mit heutigen Systemen sicher das kleinere ist) wurden von Microsoft in etwa 65.000 Fehler gemeldet. Das System galt als professionelles System (C2-Zertifizierung) und Microsoft hat alle Anstrengungen unternommen, möglichst viele davon zu finden. Wir wissen heute, dass auf Grund ökonomischer Überlegungen ein vollständiges Auffinden der Fehler nicht möglich ist. Ungefähr 3-4% aller Fehler schaffen es trotz professioneller Testtätigkeit, in die Produktion, d.h. zum Anwender zu gelangen. Das wären dann also circa 2000 Fehler, über die sich Anwender weltweit aufregen können.

Diese 2000 Fehler werden wir beim besten Willen und sorgfältigster Arbeit nicht in der zur Verfügung stehenden Zeit und Ressourcen finden können. Tatsächlich müssen die Tester für die abschließenden Integrationstests auch nur in etwa 18.000 Fehler finden. Die restlichen Fehler wurden schon in der Erstellung des Programmes entdeckt.

Betriebssysteme sind umfangreich. Doch auch in einer kommerziellen Anwendung bewegt sich die Anzahl der zu findenden Fehler zwischen 1000 und 4000. Vielleicht können wir nicht alle finden, doch wir wollen die finden, auf die der Anwender zwangsläufig stoßen muss. Und alle diese Fehler finden sich, wenn wir die typischen Anwendungsfälle des Anwenders untersuchen. Bei Software-Projekten, die bereits bestehende Software um Funktionalität erweitern, kennen wir oft nicht die Anwendungsfälle. Oder wir finden sie nicht explizit beschrieben.

Der professionelle Tester wird in so einem Fall sich selbst eine Liste der Anwendungsfälle zusammenstellen und darauf achten, die zugehörigen Geschäftsregeln möglichst vollständig zu erfassen. Wir enden dann mit einer Schar von Testfällen, deren Gesamtzahl sich so errechnet. Für jeden Anwendungsfall gibt es pro zugehöriger Geschäftsregel einen Testfall. Der Testfall testet die Verletzung einer Geschäftsregel. Für den sogenannten Schönwetterflug gibt es dann noch eine Reihe von Testfällen, welche besondere erlaubte Eingabevarianten testen. Die Auswahl richtiger Testfälle wird im Abschnitt „Kann man besser testen“ beschrieben.

Tags: ,

Leave a Reply