Human Testing

Aus THM-Wiki
Wechseln zu: Navigation, Suche

Der Begriff Human Testing umfasst eine Reihe von Verfahren, um Programmcode ohne den Einsatz von Computern auf Fehler zu testen.

Einleitung

Lange Zeit arbeiteten Programmierer mit der Annahme, dass ein geschriebener Programmcode ausschließlich von einem Computer ausgeführt wird. Man bedachte aber nicht, dass womöglich Menschen eines Tages diesen Programmcode lesen wollen. Außerdem sah man in der Programmausführung die einzige Möglichkeit, ein Programm auf seine Korrektheit zu testen. In den frühen 70er Jahren änderte sich diese Einstellung durch den Anstoß einiger Programmierer, die das Lesen von Programmcode durch Personen als bedeutenden Teil eines umfassenden Testablaufs und der Fehlersuche sahen.

Heute lesen zwar nicht alle Softwaretester den Programmcode, aber dieses Konzept gilt als Teil eines Softwaretests und ist weit anerkannt. Es gibt einige Faktoren, die den Einsatz von Human Testing bestimmen:

  • die Größe der Anwendung
  • die Größe des Entwicklerteams
  • die Zeitleiste einer Softwareentwicklung

In den folgenden Abschnitten der Ausarbeitung werden einige Verfahren des Human Testing beschrieben. Die dabei eingesetzten Methoden sind in der Fehlersuche ziemlich effektiv. Die Fehlererkennungsquote ist sogar so hoch, dass man den Einsatz von einer oder mehreren Methoden des Human Testing sogar empfiehlt. Grundsätzlich sollte man diese Methoden zwischen der Programmfertigstellung und dem computergestützten Softwaretest einsetzen. Man kann entsprechende Methoden auch schon während der Entwicklung in früheren Abschnitten der Programmierphase einsetzen. Es ist zum Beispiel denkbar, dass zum Ende jedes Designabschnitts das Human Testing eingesetzt wird. Darauf wird in dieser Ausarbeitung allerdings nicht eingegangen.

Kritiker bemängeln am Human Testing, dass die Ergebnisse von Menschen weniger formal sind wie beispielsweise mathematische Beweise durch einen Computer. Allerdings unterstützt das Human Testing die Produktivität und Zuverlässigkeit auf mehrere Wege:

  • je früher Fehler gefunden werden, desto niedriger sind die Kosten zur Beseitigung
  • je früher Fehler gefunden werden, desto wahrscheinlicher ist es, dass man ihn richtig behebt.
  • das Bewusstsein eines Programmierers stellt sich beim computergestützten Testen um: er mächte das Problem so schnell wie möglich lösen. Wegen diesem Druck macht der Programmierer beim Korrigieren von Fehlern mehr Fehler, als wenn er diese Fehler früher gefunden hätte.

Code Inspection und Walkthrough

Die zwei üblichen Methoden des Human Testing werden Code Inspections und Walkthrough genannt. Da diese Methoden viel gemein haben, wird in diesem Abschnitt auf ihre Gemeinsamkeiten eingegangen. Die Unterschiede werden in den jeweiligen Unterkapiteln erklärt. Inspections und Walkthroughs werden von einer Gruppe von Personen durchgeführt, die einen Programmcode lesen oder visuell prüfen. Beide Methoden setzen für die Teilnehmer eine vorbereitende Arbeit voraus. Den Höhepunkt bildet eine Teilnehmersitzung, in der alle Teilnehmer ihre Gedanken austauschen und diskutieren. Ziel dieser Sitzung ist es ausschließlich, Fehler im Programmcode zu finden. Auf Lösungsansätze und Korrekturen dieser Fehler wird nicht eingegangen.

In einem Walkthrough besteht die Gruppe aus 3 oder 4 Personen. Darunter sollte genau ein Programmierer des zu untersuchenden Programmcodes sein. Dadurch ist gewährleistet, dass der Programmtest größtenteils durch objektive Personen durchgeführt wird. Erfahrungen zeigen, dass ein Test uneffektiver ist, wenn ein Programmcode ausschließlich von seinem Autor getestet wird. Inspections und Walkthroughs sind eine Verbesserung der mittlerweile veralteten Methode des Desk Checking. Als Desk Checking wird der Prozess bezeichnet, in dem ein Programmierer seinen eigenen Programmcode vor dem Computertest durchliest. Inspections und Walkthroughs sind effektiver, weil neben dem Programmautor auch andere Personen mit einer neutralen Haltung am der Fehlersuche teilnehmen.

Ein weiterer Vorteil von Walkthroughs ist, dass die Stelle eines Fehlers sofort bekannt ist. Dies wirkt sich positiv auf eine kürzere Korrekturzeit aus, wodurch die Projektkosten auch geringer gehalten werden. Die Methode des Walkthrough deckt eine Reihe von Fehlern auf, welche man später in einem Durchgang korrigieren kann. Im Gegensatz dazu zeigt das computergestützte Testen in der Regel nur die Auswirkungen von Fehlern: entweder terminiert das Programm nicht oder es wird ein falsches Resultat ausgegeben. Fehler können bei dieser Methode nur Schritt für Schritt korrigiert werden.

Die Methoden Inspection und Walkthrough finden 30-70% der Fehler. Diese Zahlen beziehen sich auf alle Fehler, die bis Ende der Testphase gefunden werden. Fehler, die schon in der Anforderungsanalyse gemacht werden, können mit diesen Methoden nicht gefunden werden.

Eine berechtigte Kritik an dieser Statistik ist, dass die Methoden nur einfache Fehler finden. Die schweren, unklaren oder komplizierten Fehler hingegen können nur durch einen Computertest gefunden werden. Softwaretester bestätigen, dass Human Testing bei einigen Fehlertypen viel effektiver ist wie das computergestützte Testen. Bei anderen Fehlertypen hingegen ist das Testen mit dem Computer effektiver. Human Testing und Computer-based Testing ergänzen sich somit gegenseitig gut. Die Fehlererkennungsrate sinkt, sobald eine von beiden Methoden nicht verwendet wird.

Human Testing ist sowohl für neu geschriebenen Programmcode, als auch für Programmänderungen geeignet. Erfahrungsgemäß sind Programmänderungen fehleranfälliger als neu geschriebene Programme.

Code Inspection

Code Inspection besteht aus einer Reihe von Abläufen und Fehlererkennungstechniken für eine Gruppe Personen, um Programmcode zu lesen. Die Gruppe besteht gewöhnlich aus 4 Personen und trifft sich zu einer Sitzung. Einer dieser Personen nimmt die Rolle des Moderators ein. Der Moderator sollte ein kompetenter Programmierer sein, allerdings sollte er nicht der Autor des zu untersuchenden Programmcodes sein. Details über das Programm müssen dem Moderator auch nicht bekannt sein. Zu den Aufgaben des Moderators gehören:

  • das Planen von der Sitzung
  • das Verteilen von Materialien für die Sitzung
  • das Leiten der Sitzung
  • das Protokollieren aller gefundenen Fehler
  • die Sicherstellung, dass alle Fehler danach korrigiert werden

Der Moderator ist vergleichbar mit einem Ingenieur in der Qualitätssicherung. Das zweite Mitglied der Gruppe ist der Programmierer des vorliegenden Programmcodes. Die restlichen Gruppenmitglieder sind in der Regel der Programmdesigner, sofern dies nicht zugleich der Entwickler ist, und ein Testspezialist.

Mehrere Tage vor der Sitzung verteilt der Moderator die Ausdrucke des Programmcodes und die Designspezifikation an alle Teilnehmer. Von den Teilnehmern wird erwartet, dass sie sich damit im Voraus vertraut machen. Während der Sitzung gibt es folgende Abläufe:

  1. Der Programmierer liest Zeile für Zeile die Logik des Programms laut vor. Während dieses Vortrags können andere Teilnehmer Zwischenfragen stellen und Fehler im Programmcode finden. Beim Vorlesen findet der Programmierer weniger Fehler als andere Teilnehmer. Das laute Vorlesen stellt somit eine effektive Methode dar, dass möglichst viele Fehler gefunden werden.
  2. Das Programm wird analysiert mit Zuhilfenahme einer Kontrollliste, die gewöhnliche Fehler auflistet. Eine solche Kontrollliste wird im nächsten Abschnitt dargestellt.

Der Moderator muss außerdem dafür sorgen, dass die Diskussion eine sinnvolle und produktive Linie beibehält und die Teilnehmer sich nur darauf konzentrieren, Fehler zu finden und nicht zu korrigieren. Für die Korrektur ist ausschließlich der Programmierer nach der Sitzung zuständig.

Nach der Sitzung überreicht jeder Teilnehmer dem Programmierer eine Liste der gefundenen Fehler. Ist die Anzahl der gefundenen Fehler hoch oder ist eine größere Abänderung des Programmcodes unvermeidbar, wird der gesamte Programmcode oftmals in einer neuen Sitzung einer erneuten Code Inspection unterzogen. Die Liste aller Fehler wird außerdem analysiert, kategorisiert und dazu benutzt, die Kontrollliste zu verfeinern, um künftige Code Inspection effektiver zu machen.

Die Zeit und der Ort einer Code Inspection sollte gut geplant sein, um äußere Störungen zu vermeiden. Die Dauer einer Sitzung umfasst am sinnvollsten 90 bis 120 Minuten. Erfahrungsgemäß sind längere Sitzungen kontraproduktiv. In den meisten Code Inspection werden ca. 150 Programmbefehle geprüft. Lange Programmcodes werden auf mehrere Inspections aufgeteilt.

Für eine erfolgreiche Inspection muss von jedem Teilnehmer eine passende Haltung eingenommen werden. Fühlt sich der Autor des Programmcodes durch die Inspection persönlich angegriffen und verteidigt er sich, wirkt sich dieses Verhalten negativ auf das Endresultat aus. Auch hier ist zu erwähnen, dass das Ziel der Inspection ausschließlich das Finden von Fehlern ist.

Eine Inspection hat eine Reihe von positiven Nebeneffekten. Der Programmierer bekommt eine Rückmeldung, was Programmierstil, die Wahl des Algorithmus oder Programmiertechniken angeht. Die anderen Teilnehmer bekommen einen Einblick in den Programmierstil und Programmierfehler eines anderen Programmierer. Letztlich bietet die Inspection eine Möglichkeit, fehleranfällige Programmteile relativ früh aufzudecken und diese später bei dem computergestützten Test genauer zu untersuchen.

Eine Fehlerkontrollliste für Inspections

Als ein wichtiger Bestandteil einer Inspection gilt die Benutzung einer Fehlerkontrollliste. Diese Fehlerkontrollliste dient dazu, ein Programm auf gewöhnliche Fehler zu überprüfen. Betrachtet man im Allgemeinen Fehlerkontrolllisten, so ist auffällig, dass sich viele Überprüfungspunkte auf optische Fehler und nicht auf wirkliche Fehler beziehen. So wird zum Beispiel danach gefragt, ob die Kommentare aussagekräftig genug sind oder Codeblöcke (z.B. if-else) richtig ausgerichtet sind. In diesem Abschnitt nenne ich eine sinnvolle Fehlerkontrollliste, die sich auf eine Studie über oft gemachte Programmierfehler stützt. Die Kontrollliste ist größtenteils sprachenunabhängig, damit man sie auf den Programmcode unterschiedlicher Programmiersprachen anwenden kann. Um die Fehlersuche zu optimieren, ergänzt man diese Liste um Fehler, die in einer bestimmten Programmiersprache häufig auftreten. Die in einer Inspection gefundene Fehler fügt man ebenfalls hinzu, um sie bei weiteren Inspections zu benutzen.

Die folgende Liste gibt einen Einblick, wie eine Fehlerkontrollliste aufgebaut sein kann:

Fehler bei der Datenreferenzierung
  • Besitzt eine referenzierte Variable einen Wert oder ist sie nicht initialisiert?

Dieser Fehler tritt sehr häufig und in ganz unterschiedlichen Fällen auf. Für jeden Verweis, egal auf welchen Datentyp, sollte geprüft werden, ob die Variable zum Zeitpunkt des Zugriffs einen Wert besitzt.

  • Befindet sich bei Verweisen auf Arrays der benutzte Index im vorher deklarierten Bereich?
  • Sind die Indexwerte eines Arrays vom Datentyp Integer?

Dies ist mittlerweile in einigen Sprachen irrelevant (assoziative Arrays).

  • Ist der Speicher, auf den Zeiger oder Variablen referenzieren, auch beim Zugriff über diese noch zugewiesen?

Ein Fehler tritt auf, wenn die Lebenszeit des Zeiger länger ist als die des Speicherbereichs. Dies ist beispielsweise der Fall, wenn innerhalb einer Prozedur ein Zeiger auf eine lokale Variable zeigt und dann einer globalen Variable oder einem Ausgabeparameter zugewiesen wird. Ein späterer Zugriff über die Adresse des Zeigers führt möglicherweise zu einem Programmabbruch.

  • Besitzt eine Datenstruktur, die in verschiedenen Prozeduren oder Unter-routinen referenziert wird, auch in jeder dieser Prozedur die identische Struktur?
  • Sind alle Anforderungen einer erbenden Klasse in der vererbenden Klasse definiert?
Fehler bei der Datendeklaration
  • Sind alle Variablen explizit deklariert?
  • Ist jeder Variable der richtige Datentyp und die richtige Länge zugewiesen?
  • Gibt es Variablen, die sehr ähnliche Namen besitzen (Volt und Volts)? Auch wenn nicht zwingend ein Fehler auftritt, so können ähnliche Namen trotzdem für Verwirrung sorgen.
Fehler bei Berechnungen
  • Gibt es Berechnungen, die Variablen mit inkonsistenten Datentypen benutzen?
  • Gibt es Berechnungen mit Variablen, die einen unterschiedlichen Datentyp haben?

Dies führt nicht zwangsweise zu einem Fehler, aber die Umwandlung von Werten durch eine Programmiersprache sollte bekannt sein.


   int x = 1;

   int y = 2;

   int z = 0;

   z = x / y;

   System.out.println("z = " + z);

   // Die Ausgabe lautet: z = 0

  • Gibt es Berechnungen mit Variablen, die denselben Datentyp aber unterschiedliche Längen haben?
  • Ist der Wertebereich einer Variable kleiner als der Wert der Variablen des rechtsseitigen Audrucks?
  • Kann während einer Berechnung ein Overflow oder Underflow auftreten?

Obwohl Endergebnis im gültigen Wertebereich zu liegen scheinen, können Zwischenergebnisse außerhalb des deklarierten Wertebereichs sein.

  • Ist es möglich, dass der Divisor einer Division den Wert 0 besitzt?
  • Gibt es einen Ausdruck mit mehreren Operatoren, ist dann die Reihenfolge ihrer Ausführung bekannt?
Fehler bei Vergleichen
  • Gibt es Vergleiche zwischen Variablen, die von unterschiedlichen Datentypen sind?
  • Gibt es Vergleiche zwischen Variablen von unterschiedlicher Länge? Wenn ja, sind die Umwandlungsregeln der Programmiersprache bekannt.
  • Sind die Vergleichsoperatoren korrekt?
  • Sind die Operatoren eines boolschen Operators auch vom Typ boolean?
  • Ist die Reihenfolge der Ausführung bei der Benutzung von mehreren boolschen Operatoren in einem Ausdruck bekannt?

   If( (a == 2) && (b == 3) || (c == 3) )

Ist klar, ob zunächst && oder || ausgeführt wird?

Fehler bei Schleifen
  • Ist es möglich, dass eine Schleife trotz Bedingung nie endet?
  • Wird eine Schleife auch so oft durchlaufen, wie es gewollt ist?
Fehler bei der Schnittstelle
  • Entspricht die Anzahl der Argumente bei einem Modulaufruf der Anzahl der Parameter in der Moduldefinition?
  • Ist die Reihenfolge der Argumente auch identisch?
  • Entspricht der Datentyp des Arguments dem Datentyp, der vom Parameter in Modul verlangt wird?
  • Gibt ein Modul A einem Modul B genau so viele Argumente weiter, wie Modul B verlangt?
Fehler bei Ein- und Ausgabe
  • Wird der open-Befehl mit den richtigen Argumenten aufgerufen?
  • Gibt es genügt Speicher, um die Datei einzulesen?
  • Werden alle Dateien, die benutzt werden sollen, vorher geöffnet?
  • Werden alle Dateien nach ihrer Benutzung wieder geschlossen?
  • Sind Rechtschreib- oder Grammatikfehler in Ausgabetexten vorhanden?

Walkthrough

Ein Walkthrough besteht wie eine Code Inspection aus einer Reihe von Verfahren und Techniken zur Fehlererkennung beim Lesen von Programmcode. Wie schon geschrieben gibt es Gemeinsamkeiten zum „Code Inspection“, allerdings weichen die Verfahren leicht ab und eine andere Technik zur Fehlererkennung wird eingesetzt.

Wie eine Inspection gibt es bei einem Walkthrough auch eine durchgängige Sitzung über 1-2 Stunden. Das Team besteht aus 3-5 Personen. Auch bei diesem Verfahren des Human Testing nimmt eine Person die Rolle des Moderators ein. Eine zweite Person spielt die Rolle einer Sekretärin, die jeden Fehler protokolliert. Außerdem besetzt eine Person die Rolle eines Softwaretesters. Die Rollenbesetzung sollte variieren, allerdings muss sich der Programmierer unter den Personen befinden. Sinnvolle Personen, die an einem Walkthrough teilnehmen sind:

  • ein sehr erfahrener Programmierer
  • ein Experte für Programmiersprachen
  • ein neuer Programmierer
  • die Person, die das Programm künftig wartet
  • eine Person aus einem anderen Projekt
  • eine Person aus dem Programmierteam

Die einleitende Prozedur ist identisch mit der einer Code Inspection: den Teilnehmern werden zur Vorbereitung einige Tage vor der Sitzung Materialien ausgeteilt. Der Ablauf der Sitzung unterscheidet sich von der Code Inspection insoweit, dass die Teilnehmer nicht nur einfach den Programmcode lesen und Fehlerkontrolllisten benutzen, sondern sich in die Rolle des Computers versetzen. Die Person in Rolle des Softwaretesters bringt zur Sitzung eine kleine Anzahl von Testfällen mit, die auf einem Papier ausgedruckt sind. Die Testfälle sind mögliche Eingaben und ihre erwarteten Ausgaben im Programm oder in Modulen. Während der Sitzung wird jeder Testfall gedanklich ausgeführt. Das bedeutet, dass die Testdaten die Logik des Programms oder des Mosuls durchwandern. Der Programmzustand (beispielsweise die Werte der Variablen) werden auf dem Papier oder einen Whiteboard festgehalten.

Da Menschen nur einen minimalen Bruchteil von der Leistung eines Computers ausüben können, beschränkt man sich auf einfache und wenige Testfälle. Die Testfälle direkt spielen keine ernste Rolle, sie dienen eher dazu, eine Befragung des Programmierers über die Logik seines Programms anzukurbeln. In den meisten Walkthroughs werden mehr Fehler bei der Befragung gefunden als beim direkten Arbeiten mit den Testfällen.

Wie bei einer Inspection ist die Einstellung der Teilnehmer auch hier kritisch. Bemerkungen sollten stets an das Programm und nicht an den Programmierer gerichtet sein, d.h. Fehler sollten nicht als Schwäche des Programmierers betrachtet werden.

Die Nebeneffekte bei einem Walkthrough sind die gleichen wie die bei einer Inspection.

Desk Checking

Ein drittes Verfahren des Human Testing ist das veraltete Desk Checking. Darunter versteht man im Grunde eine Inspection oder einen Walkthrough einer einzelnen Person: eine Person liest Programmcode, überprüft ihn mit Hilfe einer Fehlerkontrollliste und durchwandert den Programmcode mit Testdaten.

Für die meisten Personen ist Desk Checking ein relativ unproduktives Verfahren. Ein Grund dafür ist, dass dieser Prozess insgesamt undiszipliniert ist. Ein weiterer und wichtiger Grund ist, dass es gegen ein schon oben erwähntes Testprinzip verstößt: Personen, die ihren eigenen Programmcode testen, arbeiten grundsätzlich uneffektiv. Daher eignet sich das Desk Checking am besten für Personen, die den Programmcode nicht geschrieben haben. Eine Inspection oder ein Walkthrough sind trotzdem westenlich effektiver. Der Grund hierfür ist die Synergie des Teams. Die Teamsitzung fördert ein gesundes Klima des Wettbewerbs. Menschen präsentieren sich gerne vor anderen, indem sie Fehler finden. Dies ist beim Desk Checking natürlich nicht möglich, weil es keine weiteren Personen gibt. Kurz gehalten ist Desk Checking immer noch besser, als wenn man den Programmcode überhaupt gar nicht prüft. Allerdings ist dieses Verfahren veraltet und weniger effektiv wie die bisher genannnten Verfahren.

Peer Rating

Das letzte Verfahren des Human Testing ist nicht damit verbunden, ein Programm zu testen und Fehler in diesem zu finden. Es ist trotzdem erwähnenswert, weil es im Zusammenhang steht mit der Idee, einen Programmcode zu lesen.

Peer Rating ist eine Technik, um unbekannte Programme auf seine Qualität, Wartung, Erweiterbarkeit, Bedienbarkeit und Übersichtlichkeit zu beurteilen. Das Ziel dieser Technik ist es dem Programmierer eine Selbsteinschätzung zu bieten.

Ein Programmierer wird ausgewählt, um den Prozess des Peer Rating zu verwalten. Dieser Verwalter bestimmt der Reihe nach 6-20 Personen. 6 Personen sind notwendig, um eine Anonymität zu wahren. Die Teilnehmer sollten dasselbe Hintergrundwissen besitzen. Es macht keinen Sinn, Java-Programmierer mit Assembler-Programmierer auszuwählen. Jeder Teilnehmer wählt zwei seiner selbst geschriebenen Programme. Dabei soll das eine Programm das qualitativ hochwertigste sein, das andere das nach seiner Meinung am unsaubersten programmierte Programm.

Nachdem die Programme gesammelt sind, werden sie willkürlich an die Teilnehmer ausgeteilt. Jedem Teilnehmer werden 4 Programme zugewiesen, um ein Review durchzuführen. Darunter sind 2 gut geschriebene Programme und 2 schlecht geschriebene Programme. Für den Teilnehmer ist die Konstellation allerdings unklar. Jede Person beschäftigt sich mit jedem Programm 30 Minuten und füllt jeweils ein Bewertungsformular aus. Nach den Reviews beurteilt jeder Teilnehmer die Qualität der Programme. Das Bewertungsformular beinhaltet Fragen, die mit Hilfe einer Skale von 1 bis 7 (1 - definitiv ja, 7 - definitiv nein) zu beantworten sind:

  • Ist das Programm einfach zu verstehen?
  • Ist das high-level Design sichtbar und angemessen?
  • Ist das low-level Design sichtbar und angemessen?
  • Würde es für Sie einfach sein, das Programm abzuändern?
  • Wären Sie stolz, wenn dies Ihr Programm wäre?

Außerdem wird der Teilnehmer nach weiteren Bemerkungen und Anregungen zur Verbesserung des Programms gefragt.

Nach den Reviews werden die Bewertungsformulare von 2 Programmen, den jeweiligen Programmierern gegeben. Außerdem wird jedem Programmierer eine zusammenfassende Statistik ausgeteilt, die ihre Programme in einer Gesamtliste bewertet zeigen. In einer Detailliste aller Programme kann man erkennen wie man ein bestimmtes Programm im Vergleich mit anderen Programmierern bewertet hat. Das Ziel dieser Technik ist es, dass ein Programmierer durch die ausgefüllten Bewertungsformulare eine Selbsteinschätzung der Skills seiner Programme bekommt.

Literatur

  • Glenford J. Myers, Corey Sandler: The Art of Software Testing, 2. Aufl., 2004, S. 21-42, ISBN 0471469122