Читать книгу Softwaretest in der Praxis - Stefan Schmerler - Страница 7
Оглавление3 Testprozess und Testphasen
Testprozesse in der Softwareentwicklung sind in der Regel gut strukturierte Prozesse, die sich insbesondere in größeren Unternehmen über viele Bereiche und Personen erstrecken. Mit den Jahren wurden eine Reihe von Entwicklungsmodellen und Testprozessen für Software vorgestellt sowie verschiedene Methoden für deren Beurteilung. Die wesentlichen Ansätze werden in diesem Kapitel vorgestellt, zudem die typischen Phasen, in welche sich ein typischer Testprozess gliedert.
Das Entwicklungsmodell
bestimmt den Testprozess.
Testprozesse sind stets abhängig von den zugrunde liegenden Entwicklungsmodellen. Auf die einzelnen Testphasen wird im weiteren Verlauf dieses Kapitels noch ausführlich eingegangen.
Test Process Improvement und
Test Management Approach
Erwähnenswert im Hinblick auf die Etablierung und Verbesserung von Testprozessen in Unternehmen wäre hier u. a. die strukturierte Methode Test Process Improvement [11], mit deren Hilfe die Reife von Testprozessen analysiert und bewertet werden kann. Ergänzend steht mit TMap (Test Management Approach) ein Modell für das Testen und die Qualitätssicherung von Software zur Verfügung, in dem die wesentlichen Aspekte, das Umfeld und die Vorgehensweise beim Test strukturiert beschrieben werden. Somit ist TMap spezieller als andere Prozessmodelle oder das V-Modell, die den gesamten Prozess der Softwareentwicklung betrachten. Es zielt auf die Strukturierung von Tests ab, weniger auf die Optimierung des Testprozesses.
Ein Testprozess wird beschrieben
als strukturiertes Phasenmodell.
Pol, Koomen und Spillner beschreiben in [2] einen Softwaretestprozess anhand eines Phasenmodells. Sie strukturieren dieses Phasenmodell in die Phasen Testvorbereitung, Testspezifikation, Testdurchführung und -auswertung sowie Testabschluss. Darüber hinaus sieht der Testprozess die Rahmenfunktionen Planung und Verwaltung vor. Das Vorgehen ist generisch, d. h. es wird – jeweils nach Erfordernis – auf unterschiedlichen Ebenen angewendet, auf das Gesamtprojekt, auf jede Teststufe und letztlich auch auf einzelne Testobjekte und Testfälle.
TAKT
Testaktivitäten werden hierbei rollenspezifisch zu sog. Testfunktionen zusammengefasst: Testen, Testmanagement, methodische Unterstützung, technische Unterstützung, funktionale Unterstützung, Verwaltung, Koordination und Beratung, Anwendungsintegrator und beim Einsatz von Testautomatisierung auch TAKT (Testen, Automatisierung, Kenntnisse, Tools), genauer TAKT-Architekt und TAKT-Ingenieur. Diese Funktionen bzw. Rollen haben Schwerpunkte in bestimmten Testphasen und können im Projekt selbst eingerichtet sein oder über spezialisierte Organisationseinheiten einbezogen werden.
International Software Testing
Qualifications Board (ISTQB)
Bei anderen Autoren oder Institutionen finden sich zum Teil andere Gruppierungen und andere Bezeichnungen, die aber inhaltlich meist mehr oder weniger auf dasselbe hinauslaufen. So wird bei ISTQB (International Software Testing Qualifications Board) der fundamentale Testprozess mit den folgenden Hauptaktivitäten definiert [12]: Testplanung und -steuerung, Testanalyse und -entwurf, Testrealisierung und -durchführung, Bewertung von Testende-Kriterien und Bericht sowie Abschluss der Testaktivitäten.
die Normen ISO/IEC/IEEE 29119
Im September 2013 wurde die Norm ISO/IEC/IEEE 29119 Software Testing veröffentlicht, die international erstmals viele ältere, nationale Normen des Softwaretestens, wie z. B. die IEEE 829, zusammenfasst und ersetzt. Die Normreihe ISO/IEC 25000 ergänzt dies um Aspekte des Softwareengineerings als Leitfaden für die gemeinsamen Qualitätskriterien und ersetzt die Norm ISO/IEC 9126.
3.1 Wasserfallmodell nach Boehm
sequenzielles Entwicklungsmodell
Das Wasserfallmodell [13] kann als Pionier der definierten Softwareentwicklungsprozesse angesehen werden. In der heutigen industriellen Softwareentwicklung kaum noch von Bedeutung, war es seinerzeit Wegbereiter und Vorstufe heutiger strukturierter Entwicklungsprozesse. Es handelt sich um ein sequenzielles Entwicklungsmodell, das durch einen linearen, sequenziellen Ablauf der Entwicklungsaktivitäten charakterisiert ist.
Abb. 3-1: Wasserfallmodell nach Boehm
Am Ende jeder Phase liegt ein fertiggestelltes Ergebnis vor – in der Regel sind dies Dokumente, z. B. eine Architekturspezifikation. Da die Ergebnisse jeweils Eingaben für darauffolgende Aktivitäten bilden, muss jede Phase vollständig abgeschlossen sein, bevor die nächste Phase begonnen werden kann.
Bewertung des Wasserfallmodells
Durch die strenge Phasensequenz werden die Anwender nur in der ersten Phase, der Anforderungserfassung, in die Entwicklung miteinbezogen. Damit lassen sich Anforderungen während der Entwicklung kaum ändern. Dies ist eine erhebliche, realitätsfremde Einschränkung. Auch Analyse-, Planungs- und Entwicklungsfehler werden erst spät bemerkt. Hier bedürfte es einer Rückkopplung über mehrere Phasen.
Nachteil der Dokumentenorientierung
Da beim Wasserfallmodell der Projektablauf auf die Erstellung von Dokumenten ausgerichtet ist, werden Projektrisiken erst spät oder gar nicht erkannt. Risiken sind aber gerade im Wasserfallmodell eine kritische Größe, da sich bei Eintreten eines Risikos in einer Phase alle folgenden Schritte und somit das gesamte Projekt verzögern könnten.
3.2 Das klassische V-Modell
Links: Entwicklung,
Rechts: Integration
Im Gegensatz zum Wasserfallmodell ist das heute gängige V-Modell [14] deutlich strukturierter und besser angepasst an die Anforderungen moderner Softwareentwicklung. Auch hier haben wir ein sequenzielles Entwicklungsmodell vor uns. Die Grundidee des allgemeinen V-Modells ist, dass Entwicklungs- und Testarbeiten gleichberechtigte Tätigkeiten sind. Im linken Ast befinden sich die immer detaillierter werdenden Entwicklungsschritte, im rechten Ast die Integrations- und Testtätigkeiten auf der jeweiligen Ebene.
Das Modell sieht vor, dass in jeder Entwicklungsphase ein Testschritt unternommen wird. Man bewegt sich von links oben durch das V-Diagramm bis zur Ankunft rechts oben. Beim Systemtest prüft man z. B. gegen die horizontal auf gleicher Höhe im V-Diagramm gelisteten Softwareanforderungen, beim Abnahmetest gegen die Systemanforderungen.
Abb. 3-2: Das V-Modell in der SW-Entwicklung
Validierung: Doing the right thing?
Diese horizontalen Testschritte bezeichnet man als Validierung, gemeint ist damit die Überprüfung, ob die Entwicklungsergebnisse auf der jeweiligen Stufe noch den Kundenanforderungen entsprechen. Falls nein, kann man korrigieren, ohne lange in die falsche Richtung weiterzuarbeiten. Die Fragestellung ist hier also »Am I doing the right thing?«
Verifikation: Doing the thing right?
Unter Verifikation versteht man hingegen die Überprüfung der Korrektheit und Vollständigkeit eines Phasenergebnisses relativ zu seinen direkten Spezifikations-/Phaseneingangsdokumenten. Es ist die Überprüfung, ob der letzte Schritt fehlerfrei absolviert wurde. Die Fragestellung lautet hier »Am I doing the thing right?
3.3 Iterative und inkrementelle Entwicklungsmodelle
iterative Annäherung an die Kunden-
anforderungen in vielen Zyklen
Das Grundprinzip einer iterativen Entwicklung ist das stetige Einbringen von Kundenrückmeldungen und anderen Erkenntnissen aus dem Einsatz des aktuellen Entwicklungsstands eines Softwareprodukts in den Entwicklungsprozess. Durch diese fortgesetzte Validierung wird das Produkt schrittweise immer weiter verbessert und kann die Kundenerwartungen immer genauer und besser erfüllen. Die Software wird nicht »an einem Stück« erstellt, sondern in Form einer Abfolge von Versionsständen mit jeweils anwachsender Funktionalität – daher der Name »inkrementelles Entwicklungsmodell«.
ein schneller erster Stand, der
sukzessive erweitert wird
Das Ziel ist, mit einer Vorstufe (Basis-Features) des Produkts möglichst schnell auf den Markt zu kommen und es dann schrittweise weiter auszubauen. Man spricht auch von iterativ-inkrementeller Entwicklung. Beispiele hierfür sind der Rational Unified Process [15] und das Evolutionary Development [16]. Auch alle Formen der agilen Softwareentwicklung sind dieser Gattung von Entwicklungsprozessen zuzuordnen. Die bekanntesten sind Extreme Programming [17] und das Modell von Kanban und Scrum [18]. Letzteres Prozessmodell ist in den letzten Jahren zu großer Bekanntheit gelangt.
Automatisierung und Wiederverwen-
dung von Tests sind obligatorisch.
Aber wie sind Testaktivitäten in diesem Entwicklungsprozess zu verankern? Fest steht, dass sich der Test an die iterativ-inkrementellen Abläufen anpassen muss. Für jede Komponente müssen wiederverwendbare Tests vorhanden sein, die an jedem Inkrement wiederholt werden können. Zu beachten ist hierbei, dass für jedes Inkrement entsprechend dem jeweiligen Funktionszuwachs zusätzliche Testfälle implementiert werden müssen.
Agile Vorgehensweisen zielen auf möglichst kurze Iterationszyklen ab, z. B. wöchentlich (Weekly Builds). Eine besondere Bedeutung kommt daher der Testautomatisierung zu, die entsprechend effizient gestaltet sein muss.
Continuous Integration
Kommen mit anwachsender Softwarefunktionalität immer weitere Testfälle hinzu, muss der Testprozess mit dem Entwicklungsprozess schritthalten können. Aufgedeckte Fehlerwirkungen werden hierbei kurzfristig korrigiert. Das Projekt besitzt daher in seiner Testumgebung zu jedem Zeitpunkt ein integriertes, getestetes System. Dieses Vorgehen wird als Continuous Integration bezeichnet.
Continuous Deployment
Werden die Tests fehlerfrei durchlaufen, so kann das getestete System automatisiert in die Produktivumgebung kopiert und dort Anwendern zur Verfügung gestellt werden. Man spricht von Continuous Deployment.
Continuous Testing
Grundvoraussetzung für diese hochfrequenten, automatisierten Abläufe ist natürlich ein automatisiertes, kontinuierlich stattfindendes Testing, das man als Continuous Testing bezeichnet im Gegensatz zu einem phasenorientiert erfolgenden Testvorgang.
3.4 Teststufen in der Softwareabsicherung
Softwarearchitektur und Teststufen
Ein Softwaresystem weist in der Regel eine Struktur aus einer Reihe von Teilsystemen auf, die wiederum aus einer Vielzahl elementarer Komponenten bestehen. Die gesamte Struktur wird als Softwarearchitektur bezeichnet. Beim Testen muss das zu testende System auf diesen verschiedenen Architekturebenen geprüft werden. Der Begriff der Teststufen hat sich etabliert, jede Teststufe ist eine Instanz des Testprozesses.
phasenorientierter Test
Im Folgenden werden die einzelnen Absicherungsschritte von phasenorientierten Testprozessen näher erläutert, insbesondere im Hinblick auf das in der jeweiligen Stufe verfolgte Testziel.
Ausgangspunkt ist das Entwicklungsstufendiagramm, wie in Abb. 3-3 dargestellt. Der Entwicklungsverlauf beginnt links oben bei der Anforderungsspezifikation.
Abb. 3-3: Übersicht Teststufen im V-Diagramm
3.4.1 Unit-Test
Der Unit-Test ist der erste Testschritt im rechten Schenkel des V-Diagramms. Er setzt ein direkt mit Beginn der Implementierung der Quelltexte und überprüft den Reifegrad der Entwicklungsphase Modulentwurf, d. h. die Implementierung einzelner Softwarefunktionen und Methoden.
Testtreiber stimulieren für die Ausführung
das SUT und erfassen die Ausgaben.
Unter Testtreiber ist hierbei ein Programm zu verstehen, das es ermöglicht, ein Testobjekt aufzurufen, mit Testdaten (Stimuli) zu versorgen, die Ausgaben des Testobjekts zu erfassen, das Testergebnis zu ermitteln und das gesamte Vorgehen zu dokumentieren.
Boolean main () /* Testtreiber */
{ Boolean result;
int in_1, in_2;
/* Testdaten bzw. Stimuli aus Tabelle laden */
Lies_Eingangsdaten (&in_1, &in_2);
/* Die Testobjekte sind mit den Stimuli aufzurufen */
result = Mein_TestObjekt_1 (in_1, in_2);
/* Wir vergleichen Ist- und Sollwert */
if (TestOrakel (in_1, in_2) != result) return 0; /* Fail */
else return 1; /* Pass */
/* Testergebnis wird dokumentiert */
Testprotokoll_Testobjekt_1 (result);
/* Das zweite Testobjekt wird aufgerufen */
result = Mein_TestObjekt_2 (in_1);
...
}
Komponententest-Frameworks
Der Einsatz von Komponententest-Frameworks reduziert den Aufwand für die Erstellung der Testtreiber-Programmierung. In [19] werden Installation und Einsatz des Google C++ Testing Framework beschrieben. Vorteil einer solchen Umgebung sind einheitliche Testtreiber, die entsprechend wiederverwendet und ausgetauscht werden können. Solche Testtreiber können z. B. über eine Kommandoschnittstelle bedient werden und bieten komfortable Mechanismen zur Handhabung der Testdaten sowie zur Protokollierung und Auswertung.
Stubs sind Platzhalter noch
nicht implementierter Module.
Unter Stub (Platzhalter) ist letztlich eine leere Hülle ohne Funktion, aber mit geeigneter Schnittstelle zu verstehen, da bei Fehlen dieses Moduls keine Kompilierung erfolgen könnte. Die Erstellung von Stubs erfordert keinen Aufwand, die Möglichkeit einer Wiederverwendung ist daher nicht von Bedeutung.
Abb. 3-4: Steckbrief Unit-Test
3.4.2 Komponententest
Der nächste Integrationsschritt in der klassischen Softwareentwicklung ist die Bildung von Softwaremodulen aus einzelnen Funktionen oder Methoden. Die Absicherung dieses Schritts ist Gegenstand des Komponententests. Testziel ist also das Zusammenspiel der Funktionen oder Methoden eines Moduls.
Fehler, die im Komponenten-
test gefunden werden
Typische Defects, die beim funktionalen Komponententest gefunden werden, sind Berechnungsfehler oder fehlende bzw. fälschlicherweise durchlaufene Programmpfade durch fehlerhafte Zweigprädikate. Man spricht von algorithmischem und logischem Absicherungsumfang.
Robustheitstests und Negativtests
Auch der Test auf Robustheit ist ein weiterer wichtiger Aspekt des Komponententests. Robustheitstests müssen nicht auf Integrations- oder Systemtestebene erfolgen und sollten, dem Grundsatz kleinstmöglicher Teststufen folgend, auf Komponentenebene verortet werden. Es werden nach der Spezifikation unzulässige oder nicht vorgesehene Testdaten eingesetzt, um eine korrekte Ausnahmebehandlung (Exception Handling) zu testen. Derartige Testfälle werden auch Negativtests genannt. Fehlen solche Ausnahmebehandlungen, treten möglicherweise Wertebereichsfehler und unter Umständen Programmabstürze auf.
über die Hälfte des Codes für die Robust-
heit und Ausnahmebehandlung
Diese Ausnahmebehandlung im Testobjekt kann, verglichen mit dem eigentlichen Funktionscode, durchaus umfangreich werden. In der Praxis dienen nicht selten über 50 % des Programmcodes der Behandlung von Ausnahmesituationen und damit der Robustheit.
nichtfunktionale Eigenschaften
Neben Funktionalität und Robustheit sind im Komponententest auch Qualitätseigenschaften der Komponente wie Effizienz, Performance und Wartbarkeit zu prüfen, die auf höheren Teststufen nicht mehr oder nur mit erhöhtem Aufwand getestet werden könnten. Die Messung von Speicherverbrauch oder Reaktionszeit gehört zum Standardprogramm einer Komponententestsuite.
Komponententest prüft die
inneren Qualitätsmerkmale.
Bei dieser Gelegenheit kann man auch einen Blick auf die »inneren Werte« des Codes, z. B. seine Wartbarkeit, werfen. Wie leicht oder schwer wird es einer anderen Person einmal fallen, den Code zu ändern, zu erweitern oder überhaupt erst einmal zu verstehen? Prüfaspekte, die hier im Vordergrund stehen, sind Modularität, Kommentierung, Codestruktur, die Einhaltung von Architektur- oder Codierrichtlinien sowie die Verständlichkeit und Aktualität der Dokumentation.
Möglichkeit des White-Box-Test
Da Komponententests typische Entwicklertests sind, liegt in aller Regel Zugang zum Quellcode vor, was den Komponententest zum White-Box-Test macht, d. h. die Kenntnis der Programmstrukturen ausnutzen lässt. Der Tester kann Testfälle mithilfe seines Wissens über komponenteninterne Codestrukturen, Methoden oder Variablen entwickeln. Durch Werkzeuge wie Debugger kann der Zustand der Komponente nicht nur beobachtet, sondern auch manipuliert werden. Dies ist besonders bei Robustheitstests von besonderem Nutzen.
oft genutzt: Black-Box-Test
Trotz der Möglichkeit von White-Box-Tests werden in der Praxis viele Komponententests nur als Black-Box-Verfahren durchgeführt, d. h. im Gegensatz zum White-Box-Test nur durch Beobachtung und Stimulation der äußeren Schnittstelle des Testobjekts. Dies kann dadurch erklärt werden, dass Softwaresysteme oft aus Tausenden von Komponenten bestehen, die erst in einer höheren Aggregationsstufe sinnvoll und praktikabel einem Komponententest unterzogen werden können. Diese Aggregationseinheiten sind dann aber bereits zu groß, um sich mit vertretbarem Aufwand beim Komponententest auf Codeebene bewegen zu können.
Test-First-Ansatz und
testgetriebene Entwicklung
Ein häufig zum Einsatz kommender Ansatz für Komponententests ist es, zuerst die Tests zu erstellen und zu automatisieren und dann erst mit der Implementierung der Komponente zu beginnen. Man spricht vom Test-First-Ansatz. Dabei ist das Vorgehen stark iterativ. Der Code wird mit den vorhandenen Testfällen überprüft und sukzessive in kleinen Schritten verbessert, bis die Tests, die nach jeder Änderung im Code automatisiert durchgeführt werden, fehlerfrei durchlaufen werden. Man bezeichnet dieses Vorgehen aus offensichtlichen Gründen auch als testgetriebene Entwicklung. Auch Negativtests können auf diese Weise vor Implementierungsbeginn eingebunden werden.
Spezifika in der Automobilelektronik
Unter Komponententest versteht man im Kontext Automobilelektronik auch den Test einzelner Steuergeräte eines Steuergeräteverbunds. Dies ist der Test eines Steuergeräts oder der entsprechenden Software stand-alone, aber durchaus mit simulierter Umgebung, z. B. indem andere Komponenten (zumindest in der Kommunikation) simuliert werden. Dieses Vorgehen wird als Restbussimulation bezeichnet. Ohne eine höchst realistische Stimulation, die auch spezifikationsgerecht auf Ausgaben der zu testenden Komponenten reagiert, würde der Test aufgrund der permanent stattfindenden Plausibilitätsprüfungen der Eingangswerte an den Steuergeräten mit Eintrag in den Fehlerspeicher abgebrochen werden. Das Steuergerät würde also eine Fehlerroutine einleiten, die weiteres Testen verhindert.
Komponententest ist notwendig,
aber nicht hinreichend.
Ein erfolgreicher Komponententest ist eine notwendige, aber keine hinreichende Bedingung für den Integrationserfolg. Viele Auffälligkeiten stellen sich erst im Verbund ein. Im Bereich des Netzwerkmanagements, bei spezifischen Protokollen wie Service Discovery oder bei im Verbund dargestellten komplexen Funktionen stößt der Komponententest an seine Grenzen. Ein sich anschließender Integrationstest ist unbedingt erforderlich.
Abb. 3-5: Steckbrief Komponententest in der klassischen SW-Entwicklung
3.4.3 Integrationstest
Softwareintegration
In der klassischen Softwareentwicklung überprüft der Integrationstest, aufbauend auf dem Komponententest, das Zusammenspiel der Komponenten bzw. Funktionen oder Klassen. Gruppen dieser Komponenten werden zunächst von Testern oder Integrationsteams zu größeren Teilsystemen verbunden. Diesen Vorgang bezeichnet man als Softwareintegration.
Integrationstest
Anschließend kann getestet werden, ob das Zusammenspiel der integrierten Komponenten untereinander spezifikationskonform erfolgt. Dieser Test wird als Integrationstest bezeichnet. Er hat zum Ziel, Fehlerzustände in Schnittstellen und im Zusammenspiel integrierter Komponenten zu finden.
Integrationstest setzt
Komponententest voraus.
Wichtig für einen effizienten und erfolgreichen Integrationstest sind im Vorfeld erfolgte Komponententests. Auch bei diesen Tests können Schnittstellenfehler der Komponenten unerkannt bleiben – schon aus diesem Grunde ist ein Integrationstest unbedingt erforderlich. Ein übergeordneter funktionaler Test wäre auf Ebene des Komponententests zudem in keiner Weise leistbar.
Wiederverwendung der Test-
treiber des Komponententests
Auch beim Integrationstest werden Testtreiber benötigt, die die Testobjekte mit Testdaten versorgen und deren Ergebnisse aufnehmen und weiterverarbeiten bzw. protokollieren. Da die Testobjekte Systeme aus zusammengesetzten Komponenten sind, die keine anderen Schnittstellen nach außen aufweisen als ihre Einzelkomponenten, können vorhandene Testtreiber des Komponententests beim Integrationstest wiederverwendet werden.
Systemintegrationstest
Auch die Schnittstellen zur Systemumgebung sind Gegenstand von Integration und Test. Werden Schnittstellen zu (aus Sicht des SUT) externen Softwaresystemen – oder gar zur Hardware – getestet, spricht man von Systemintegrationstest. Er erfolgt nach dem Systemtest.
Für den Integrationstest wurden eine Reihe verschiedener Vorgehensweisen und Ausprägungen entwickelt, die im Folgenden kurz skizziert werden.
Hardware-in-the-Loop-Simulatoren
Beim Test automobiler Steuergeräteverbünde versteht man unter Integrationstest den gemeinsamen Test von Steuergeräten im Verbund. Häufig kommen Hardware-in-the-Loop-Simulatoren zum Einsatz, mit deren Hilfe die Umgebung der zu testenden Steuergeräte in Echtzeit simuliert wird. Dies betrifft also die gesamte Aktorik, Sensorik und das Umgebungsverhalten, quasi das »Restfahrzeug« aus Sicht der zu testenden Steuergeräte. Auf diese Technologie wird in einem eigenen Kapital noch explizit eingegangen.
Abb. 3-6: Steckbrief Integrationstest in der klassischen SW-Entwicklung
Hilfsmittel des Integrationstests sind
Testtreiber und Stubs (Platzhalter).
Da Systeme komponentenweise entwickelt werden, muss zwingend eine Integration erfolgen. Diese Integration kann nach unterschiedlichen Strategien abgesichert werden. Allen Ansätzen gemeinsam ist, dass Komponenten beim Test durch Treiber gesteuert werden, die es ermöglichen, ein Testobjekt ablaufen zu lassen, zu stimulieren und dessen Ausgaben zu erfassen. Zum anderen kommen beim Integrationstest Stubs zum Einsatz, also interfacekonforme, aber leere Hüllen ohne Funktion, die für den Test anderer Komponenten benötigt werden, z. B. um eine Kompilierung zu ermöglichen.
Abb. 3-7: Abhängigkeitsgraph mit Baumstruktur
Zur Darstellung der Prinzipien des Integrationstests werden Abhängigkeitsgraphen mit Baumstruktur genutzt (Abb. 3-7). Diese Graphen sind zyklenfrei, ihre Knoten sind Komponenten des SUT.
3.4.3.1 Big-Bang-Strategie
von Anfang an »das volle Programm«
Unter Big-Bang-Integrationsteststrategie versteht man den gleichzeitigen Test aller Komponenten im Gesamtsystem, also keine stufenweise, sukzessive Vergrößerung des Testgegenstands, sondern sofort das »volle Programm«.
Diese Strategie findet Anwendung bei kleinen Änderungen eines bereits ausgiebig getesteten Systems oder bei kleinen, sehr überschaubaren Systemen. Der Vorteil dieser Strategie liegt im geringen Aufwand, da keine Treiber zu erstellen sind.
Man lernt sofort das Gesamt-
system kennen, Fehler sind
aber schlecht lokalisierbar.
Als Nachteil ist die schwierige Lokalisierung von Fehlern zu sehen, sollten diese aufgetreten sein. Wir alle kennen das Phänomen der nicht wirklich hilfreichen Meldung »Es ist ein unbekannter Fehler aufgetreten«. Wir haben es beim Big-Bang-Test quasi mit einem Schnellschuss zu tun, der uns selbst im erfolgreichen Fall nicht viel weiterhilft, denn Schnittstellenfehler oder kompensierte/überdeckte Fehler müssen im Gegensatz zu einem Test auf Modulebene nicht zu Tage treten. Darüber hinaus kann die Wartezeit, bis ein Big-Bang-Test möglich ist, als verlorene Testdurchführungszeit angesehen werden, denn für die Durchführung dieser Tests muss das Gesamtsystem implementiert und testbar sein. Kann der Test dann durchgeführt werden, werden die Tester damit konfrontiert, dass alle Fehlerwirkungen geballt und gleichzeitig auftreten und nicht sukzessive beseitigt werden konnten. Es ist oft sehr schwierig, das System überhaupt zum Laufen zu bringen.
Nichtinkrementelle Integration nach dem Big-Bang-Prinzip sollte außer unter den oben genannten Bedingungen vermieden werden. Andererseits kommt die inkrementelle Systementwicklung für die Anwendung des Big-Bang-Integrationstests durchaus in Frage. In vielen iterativen Zyklen reift und wächst ein Gesamtsystem bei häufiger Validierung gegen die Anforderungen. Dies erfordert implizit immer den Gesamtkontext, d. h. den Test des Gesamtsystems. Da die Entwicklungsinkremente von Zyklus zu Zyklus immer überschaubar bleiben, entsteht bei regelmäßiger, hochfrequenter Anwendung dieser Teststrategie nicht die oben geschilderte, unkontrollierbare Fehlerhäufung, die letztlich keine konkreten Erkenntnisse mehr bringt als die Tatsache, dass das System fehlerhaft ist.
Abb. 3-8: Big-Bang-Integrationsteststrategie
3.4.3.2 Bottom-up-Strategie
Wir benötigen viele Treiber.
Bei der Bottom-up-Integrationsteststrategie wird ein Test von den Blättern des Abhängigkeitsgraphen aus in Richtung Wurzel durchlaufen. Die jeweils darüber liegende Ebene wird mit Treibern umgesetzt. Danach folgen Implementierung und Test der Ebene, in der sich die Treiber befanden (einschließlich deren Blätter).
sukzessive, kontrollierte
Erweiterung des Scopes
Der Vorteil dieses Verfahrens ist die kontrollierte und systematische Ausweitung des Testgegenstands. Zudem besteht die Möglichkeit, die Komponenten des SUT parallel zu entwickeln. Die Möglichkeit, mittels frühzeitiger Simulation ein Gesamtsystem das erste Mal »zu erfahren«, ist allerdings nicht gegeben. Treten während der Integration der Komponenten Fehler auf, ist das Ergründen der Ursachen schwieriger als bei der gleich folgenden Top-down-Strategie.
erhöhter Aufwand
Als Nachteil ist sicher der Aufwand zu sehen, der aufgrund der Treiberentwicklung deutlich höher sein kann als bei der Entwicklung des SUT. Bei geschicktem Vorgehen lässt sich der Aufwand durch Wiederverwendung der Treiber allerdings in Grenzen halten.
Für komplexe, verteilt entwickelte Systeme kommt man häufig an der Bottom-up-Strategie nicht vorbei. Sie ermöglicht die parallele, unabhängige Entwicklung verschiedener Systemkomponenten durch mehrere Teams oder Entwickler, die dann auf kleinstmöglicher Integrationsebene mit- und gegeneinander getestet werden. Eventuelle Schnittstellen- oder logische Fehler können auf diese Weise sofort erkannt werden.
Abb. 3-9: Bottom-up-Integrationsteststrategie
3.4.3.3 Top-down-Strategie
Beim Integrationstest nach der Top-down-Strategie beginnt die Absicherung beim Kontrollobjekt des SUT, also der Wurzel des Baums, mithilfe eines Treibers. Die Erweiterung des Testgegenstands erfolgt von oben nach unten in Richtung der Blätter des Abhängigkeitsgraphen (Abb. 3-10), wobei die getestete höhere Schicht jeweils als Testtreiber dient.
Abb. 3-10: Top-down-Integrationsteststrategie
stets das Gesamtsystem im Blick
Dies unterstützt eine iterative Entwicklungsweise. Zu jedem Zeitpunkt hat man das Gesamtsystem im Blick, dessen Funktionalität sukzessive erweitert und verfeinert wird. Man erhält schnell einen ersten Gesamteindruck und kann die Entwicklung der fehlenden Komponenten schrittweise vorantreiben. Ein weiterer Vorteil dieses Verfahrens ist die Tatsache, dass nur ein Treiber implementiert werden muss. Nachteil der Top-down-Strategie ist allerdings die Implementierung vieler Stubs. Da diese aber in der Regel leere Funktionen sind, bleibt der Aufwand dafür überschaubar.
3.4.3.4 Collaboration-Strategie
Die Collaboration-Strategie orientiert sich an der Funktion des zu entwickelnden Systems. Bei jedem Testdurchlauf wird der Teil des SUT betrachtet, der für eine bestimmte Funktionalität zuständig ist. Alle hierbei beteiligten Softwarekomponenten – aber nur diese – werden ausgeführt und erprobt.
Die Erprobungsreihenfolge orien-
tiert sich an der Nutzung.
Vorteil dieses Vorgehens ist die funktionsorientierte Sichtweise – die Sicht des späteren Kunden! Nichts ist wichtiger für einen schnellen Reifegradgewinn, als ein System so früh wie möglich aus Sicht des späteren Anwenders zu betrachten. Es ist allerdings schwierig, die Gesamtheit aller Funktionalitäten lückenlos zu erfassen. Hier droht bei seltenen oder nicht berücksichtigten Anwendungsfällen ein hohes Reifegradrisiko.
Das Wichtigste funktioniert zuerst,
Unwichtiges unter Umständen nie!
Andererseits werden mit dieser Strategie die wichtigen Funktionen bereits sehr früh einen hohen Reifegrad aufweisen – und zwar in vollständiger Implementierung. Je nach dem vorliegenden Einsatzziel der Software kann dies eine wichtige Eigenschaft sein. Trotz Weiterentwicklung könnte die Software nie die grundsätzliche Nutzungsmöglichkeit verlieren und z. B. für Kundenvalidierungen oder während der Wartung zur Verfügung stehen.
Abb. 3-11: Collaboration-Integrationsteststrategie
3.4.3.5 Ad-hoc-Integration
zufällige Integrationsreihenfolge
Die Komponenten werden in der zufälligen Reihenfolge ihrer Fertigstellung integriert. Dies hat den Vorteil, dass jede Komponente zum frühestmöglichen Zeitpunkt integriert werden kann, was den Gesamtprozess beschleunigt. Andererseits sind sowohl Treiber als auch Stubs zu entwickeln.
3.4.3.6 Backbone-Integration
Integration in einen
vorgefertigten Rahmen
Bei der Backbone-Integration wird vor der Integration eine Grobstruktur (Backbone) zur Verfügung gestellt, in die sukzessive die zu integrierenden Komponenten eingebaut werden. Die bereits angesprochene Continuous Integration kann als eine spezielle Form der Backbone-Strategie angesehen werden.
Der Vorteil dieses Vorgehens ist die beliebige Reihenfolge, in der die Komponenten in die Testumgebung eingebracht werden können. Andererseits ist die Backbone-Struktur explizit zu entwickeln, was einem gewissen Zusatzaufwand im Voraus entspricht.
3.4.4 Systemtest
Funktionstest des Gesamt-
systems aus Sicht des Kunden
Beim Systemtest wechselt die Perspektive der Absicherung: Testziel ist, die Leistung des gesamten Systems aus Sicht des späteren Kunden oder Anwenders zu prüfen. Allerdings liegt noch nicht das finale Produkt vor und der Test erfolgt auch nicht in der späteren realen Zielumgebung. Während des Tests orientiert man sich an der Anforderungsspezifikation des Systems, wir haben also einen Funktionstest vor uns.
Ziele des Systemtests
Der Systemtest erfordert eine möglichst realistische Stimulation des Systems von außen, um das SUT auch in großer Realitätsnähe erproben zu können. Als wichtigstes Ziel des Systemtests ist also die Validierung anzusehen, ob und wie gut das fertige System die funktionalen und nichtfunktionalen Anforderungen der Spezifikation erfüllt. Fehler und Mängel aufgrund falsch, unvollständig oder im System widersprüchlich umgesetzter Anforderungen sollen aufgedeckt werden. Spezifikationslücken sollen gefunden werden.
Der Systemtest ist eine gute Gelegenheit,
Defizite der Spezifikation zu beheben.
Wurde es im Rahmen der Spezifikationsphase versäumt, die entstehenden Dokumente zu konsolidieren und nach Klärung mit allen relevanten Projektbeteiligten auf Konsistenz und Vollständigkeit zu prüfen, muss dies nun beim Systemtest nachgeholt werden. Der Systemtest muss also unter Umständen nicht nur fehlende Anforderungen sammeln, sondern auch noch Klärungs- und Entscheidungsprozesse, die viele Monate unterblieben sind, zu einem eigentlich viel zu späten Zeitpunkt herbeiführen.
Systemtest bei agilen oder itera-
tiven Entwicklungsmodellen
Auch Projekte, die agil oder iterativ arbeiten, sehen sich damit konfrontiert, dass ihre Anforderungsbasis unvollständig oder widersprüchlich sein kann. Das Risiko, dass deshalb das Gesamtprojekt scheitert, ist aber als geringer einzuschätzen als bei sequenziellen Entwicklungsmodellen. Letztlich nutzen agile und iterative Vorgehensmodelle jede Iteration zur Validierung des Projektzwischenstands gegen die Kundenanforderungen.
Testbasis
Als Testbasis für den Systemtest dienen alle Dokumente oder Informationen, die das Testobjekt auf Systemebene beschreiben. Dies können Lastenhefte, anderweitige Spezifikationen, Benutzerhandbücher, aber auch Risikoanalysen sein.
Die Testumgebung muss der späteren Produktivumgebung der Software möglichst nahekommen. Statt Testtreibern und Stubs müssen also auf allen Ebenen die später tatsächlich eingesetzten Hardware- und Softwarekomponenten im Testsystem installiert sein. Dies beinhaltet ggf. auch Interfacesoftware, das Netzwerk oder anderweitige Fremdsoftwaresysteme.
den Systemtest nicht in der Produktiv-
umgebung durchführen!
Um die Kosten für die Bereitstellung einer separaten Testumgebung zu sparen, wird oft der Fehler begangen, den Systemtest in der Produktivumgebung durchzuführen. Dies birgt die Gefahr, dass die Produktivumgebung des Kunden beeinträchtigt wird. Teure Systemausfälle auf Kundenseite können die Folge sein. Zudem haben Tester nur geringe Kontrolle über Konfigurationen und Parameter der Produktivumgebung des Kunden. Wichtige Randbedingungen des Tests werden unter Umständen schleichend und unbemerkt verändert.
eine Aufwandsbetrachtung
Der Aufwand eines hinreichenden Systemtests kann durchaus erheblich sein und sollte nicht nur »als letzte Schleife« betrachtet werden. Analysen [20] zeigen, dass bei Beginn des Systemtests erst etwa die Hälfte der Test- und Qualitätssicherungsarbeiten geleistet sind.
Spezifika in der Automobiltechnik
In der Automobiltechnik erfolgt ein Systemtest der E/E-Komponenten im Fahrzeug oder in einem Hardware-in-the-Loop-(HiL-)Labor. Die zu testenden Steuergeräte liegen real vor, das gesamte umgebende »Restfahrzeug« wird in Echtzeit simuliert bis hin zur gesamten Aktorik und Sensorik. Auf diese Weise verhalten sich Steuergeräte exakt wie im Fahrzeug, ein Labor verfügt aber über bessere analytische Möglichkeiten als eine Testumgebung im Fahrzeug. Das Verhalten des virtuellen Fahrzeugs kann gezielt für die Durchführung spezifischer Tests eingestellt werden.
Wichtig für den Systemtest ist also die Sicht von außen und dies erfordert den Betrieb des Systems in seiner realen (Fahrzeug) oder in einer realitätsnah simulierten (HiL-Labor) Umgebung.
Abb. 3-12: Steckbrief Systemtest in der klassischen SW-Entwicklung
3.4.5 Produkttest
erster Test in der späteren Zielumgebung
Unter einem Produkttest versteht man rein funktional einen Systemtest in der realen Zielumgebung. In der Automobiltechnik ist dies z. B. eine kundennahe Fahrerprobung im realen Fahrzeug. Das zu testende Steuergerät wird hierbei im realen Fahrbetrieb durch Testingenieure des Automobilherstellers im Zielfahrzeug erprobt. Die analytischen Möglichkeiten sowie die Reproduzierbarkeit sind eingeschränkt, aber letztlich haben wir hier den finalen Fahrversuch vor uns, der trotz aller simulativen Möglichkeiten immer stattfinden muss.
Abb. 3-13: Steckbrief Produkttest in der klassischen SW-Entwicklung
3.4.6 Abnahmetest
Testziel ist es, Auftraggebern Hilfestellung
bei der Software-Abnahme zu geben.
Der Abnahmetest adressiert die Kunden-/Auftraggeber-Situation bei der Entwicklung einer fremdbeauftragten Software. Ziel ist es, mithilfe von Tests des finalen Produkts einem Auftraggeber eine Entscheidungsgrundlage hinsichtlich Akzeptanz oder Ablehnung des Gewerks zu geben. Ein Abnahmetest aus Sicht des Kunden oder Benutzers wird deshalb auch als Akzeptanztest bezeichnet. Hierbei werden in der Regel häufige Anwendungsfälle abgeprüft, stichprobenartig auch Robustheitstests gegen typische Fehlersituationen oder Fehlbedienungen. Neben der funktionalen Absicherung werden bei Abnahmetests auch interne Qualitätsmerkmale wie die Einhaltung von Codierrichtlinien und Standards überprüft.
typische Arten des Abnahmetests
Typische Formen des Abnahmetests sind also ein Test auf vertragliche Akzeptanz, auf Benutzerakzeptanz (Benutzerabnahmetest) sowie ein Feldtest (Alpha- und Beta-Test).
Testbasis
Als Testbasis können alle Dokumente und Informationen dienen, die das Testobjekt aus Anwendersicht beschreiben. Dies können Anwender-/Systemanforderungen und Lastenhefte sein sowie Geschäftsprozesse und Risikoanalysen, aber auch einzuhaltende Gesetze und regulatorische Vorschriften. Bei letzterem spricht man von regulatorischem Abnahmetest.
Akzeptanztestfälle müssen
vom Kunden erstellt werden.
Es ist besonders wichtig, dass der Kunde die Akzeptanztestfälle selbst erstellt, sie zumindest aber einem intensiven Review unterzieht, denn der Softwarehersteller könnte die vertraglich vereinbarten Akzeptanzkriterien missverstanden haben.
nicht auf den Akzeptanztest
warten: Prototypen einsetzen!
Wenn allerdings beim Akzeptanztest gravierende Probleme zutage treten, ist es in Softwareprojekten für grundlegende Änderungen meistens zu spät. Aus diesem Grund ist es stark zu empfehlen, schon in frühen Projektphasen Prototypen von repräsentativ ausgewählten Vertretern der späteren Anwender begutachten zu lassen.
Abb. 3-14: Steckbrief Abnahmetest in der klassischen SW-Entwicklung
3.4.7 Produktionstest
Auch fehlerfreie Produzierbarkeit
und Inbetriebnahme sicherstellen
Beim Produktionstest geht es nicht mehr um die funktionale Korrektheit des Systems – diese wurde in den vorherigen Teststufen bereits nachgewiesen – sondern um den Nachweis der fehlerfreien Produzierbarkeit, also den Ausschluss von Produktionsfehlern des fertig entwickelten und abgesicherten Produkts. Hier gilt der Grundsatz, dass die beste Entwicklung vergebens ist, wenn das Produkt, aus welchen Gründen auch immer, nicht fehlerfrei und in ausreichender Qualität produziert werden kann. Für klassische Bürosoftware besitzt dieser Test keine Relevanz, bei eingebetteten oder mechatronischen Systemen ist das aber durchaus der Fall, denn auch eine Parametrierung und werksseitige Inbetriebnahme des fertigen Produkts kann durch softwareseitige Fehler verhindert werden.
Abb. 3-15: Steckbrief Produktionstest
Spezifika in der Automobiltechnik
In der Automobiltechnik bedeutet dies in Bezug auf elektronische Steuergeräte neben grundlegenden Funktionstests auch die richtige Kontaktierung von Steuergeräten, Aktorik, Sensorik und Leitungssatz. Dies wird während der Produktion stichprobenhaft anhand spezifischer Prüfroutinen durch Produktionstests abgesichert. Der Produktionstest steht in der Regel unter besonderen Randbedingungen, da aufgrund des Serienproduktionsbetriebs nur wenig Zeit zur Verfügung steht, um auf aufgetretene Fehler zu reagieren.
3.4.8 Feldtest
Als produktionsnachgelagerte Teststufen sind Feldtest und Regressionstest zu nennen.
Alpha-Test inhouse,
Beta-Test im Feld
Beim Feldtest wird die Software in verschiedenen Betriebsumgebungen getestet. Auch bei noch so intensivem System- und Produkttest ist es einem Hersteller kaum möglich, alle oder auch nur einen Großteil der möglichen Produktivumgebungen beim Test zu berücksichtigen. Die Produktivumgebung bzw. Nutzungsart hat durchaus Einfluss auf das abzusichernde Systemverhalten und muss daher im Testprozess Berücksichtigung finden. Softwarehäuser versenden daher im Rahmen einer sogenannten Beta-Testphase Vorabversionen der Software an einen ausgewählten Kundenkreis, um solch einen Feldtest durchzuführen. Natürlich werden auch eigene Mitarbeiter für diese Absicherung herangezogen – in diesem Fall spricht man von Alpha-Test.
3.4.9 Regressionstest und nachgelagerte Teststufen
Unter einem Regressionstest ist die erneute Absicherung eines bereits getesteten Systems nach dessen Modifikation unter Nutzung bereits vorhandener Testfälle zu verstehen. Diese Änderungen können bei der Weiterentwicklung oder auch in der Wartungsphase, also nach Verkaufsstart, im normalen Lebenszyklus der Software auftreten.
Testziele des Regressionstests
Testziel ist der Nachweis, dass nach der Fehlerbeseitigung zum einen der Fehler auch tatsächlich behoben ist – man spricht hier von der Verifikation der Fehlerbehebung. Zum anderen ist zu prüfen, ob durch die Fehlerbeseitigung möglicherweise neue Defects in das SUT eingebracht wurden oder durch den jetzt beseitigten Fehler bislang maskierte Defects ihre Fehlerwirkung zu zeigen beginnen. Hält man sich vor Augen, dass erfahrungsgemäß 5 % Neufehler bei einer Fehlerabstellung eingebracht werden, erkennt man die Wichtigkeit des Regressionstests.
Regressionstests sind aufwendig und
werden aufgrund vermeintlicher Redun-
danz oft nicht stringent durchgeführt.
Im Auge zu behalten ist in der Praxis aber immer auch der Effizienzaspekt. Regressionstests sind teuer! Die Frage ist: Was muss aufgrund einer Änderung erneut getestet werden und was nicht? Schließlich wurde ja oftmals »nur eine Zeile Code geändert«. Die Realität ist: Viele Änderungen im Code haben das Potenzial zu Seiteneffekten. Selbst wenn kein neuer Fehler eingebracht und kein maskierter Defect freigelegt wurde, ändert sich das Systemverhalten (die Änderung hatte letztlich ja einen Grund) und das neue Verhalten könnte Probleme aufwerfen, die vorher noch nicht absehbar waren. In vielen Fällen ist also beim Regressionstest von einem vollständigen Testzyklus auszugehen – so bitter das ist. In der Praxis ist daher zu empfehlen, eine Reihe von Fehlern in einer gemeinsamen Bugfix-Release zu beheben, sodass der Regressionstestaufwand in einem besseren Verhältnis dazu steht. Wenn die Ressourcen für einen vollständigen Regressionstest tatsächlich nicht zur Verfügung stehen, sollten folgende Mindestregeln eingehalten werden:
▶Wiederholung aller Tests, die eine Fehlerwirkung gezeigt haben, deren Ursache der korrigierte Fehlerzustand war. Dies wird ohnehin für die Verifikation der Fehlerbeseitigung benötigt,
▶Test aller Komponenten, die korrigiert oder geändert wurden,
▶Test aller Komponenten, die neu eingefügt wurden.
auf was am ehesten verzichten?
Auf was kann man am ehesten verzichten? Es besteht die Möglichkeit, im Testplan folgende Einschränkungen vorzunehmen:
▶Wiederholung nur derjenigen Tests aus dem Testplan, die eine genügend hohe Priorität haben,
▶bei funktionalen Tests Verzicht auf gewisse Varianten, d. h. Sonderfälle der Software,
▶Einschränkung der Tests auf bestimmte Konfigurationen wie z. B. andere Sprachen,
▶Einschränkung der Tests auf bestimmte Teilsysteme oder Teststufen.
Testautomatisierung ist Pflicht.
Damit Testfälle für einen Regressionstest wiederverwendet werden können, müssen sie wiederholbar sein. Der Nutzen einer Testautomatisierung beim Regressionstest ist also ganz erheblich.
nachgelagerte Teststufen: Test nach
Weiterentwicklung und Änderung
Ist die Software einmal fertiggestellt, kann sie viele Jahre im Einsatz sein. In dieser Zeit finden Fehlerkorrekturen, Änderungen und Erweiterungen statt. Im Folgenden wird die Vorgehensweise beim Test in dieser letzten Phase des Lebenszyklus vorgestellt.
Testen nach Software-
wartung und -pflege
Die in der Nutzungsphase einer Software eingepflegten Erweiterungen und Korrekturen werden im Rahmen einer Softwarewartung und -pflege einem spezifischen Wartungstest unterzogen. Von Softwarewartung wird gesprochen, wenn Fehlerzustände eliminiert werden, die schon immer im Code enthalten waren. Die Softwarepflege hingegen bezeichnet das Anpassen einer Software an geänderte Einsatzbedingungen, z. B. an ein neues Betriebssystem.
Welche Testfälle sind bei Software-
wartung auszuführen?
Bei der Softwarewartung, also dem Test nach Fehlerbehebung, sind in erster Linie alle Testfälle auszuführen, die in der Vorversion im Testergebnis Fail resultiert und die betreffende Fehlerwirkung gezeigt haben. Wurden Fehlerzustände behoben, die nicht durch Testfälle aufgefallen waren, sind entsprechende Testfälle zu ergänzen. Oft lässt es sich aber nicht vermeiden, bei einer Fehlerkorrektur auch das nicht auffällige Verhalten der modifizierten Software zu verändern. Dies kann absichtlich oder unbeabsichtigt erfolgen – zumindest für die bekannten Veränderungen sind entsprechend Testfälle zu ergänzen. Zusätzlich müssen aus den vorhandenen Testfällen diejenigen wiederholt werden, die aufzeigen können, dass die nicht modifizierten Anteile der betroffenen Komponente noch immer spezifikationskonformes Verhalten aufweisen.
Hotfix für dringende Fälle außerhalb
der Wartungsmaßnahmen
Nicht selten treten beim Einsatz einer Software in der Produktivumgebung Fehlerwirkungen auf, die einer sofortigen Beseitigung bedürfen und nicht bis zur nächsten Wartungsmaßnahme warten können. Die erforderliche Notlösung wird als Hotfix bezeichnet und ist in der Kürze der Zeit oft keine ausgereifte Fehlerbeseitigung. Auch die Absicherung wird im Interesse einer schnellstmöglichen Zurverfügungstellung des Hotfix nur reduziert absolviert. Die gründliche Absicherung der Maßnahme muss dann im Nachgang so schnell wie möglich nachgeholt werden.
Wartung darf kein Vorwand sein
für Einsparungen beim Test.
Aus der Tatsache, dass im Rahmen ohnehin erfolgender Wartungsmaßnahmen eine erneute Absicherung vorgesehen ist, darf allerdings nicht abgeleitet werden, dass bei der Erstentwicklung an der Absicherung gespart werden darf. Wer so handelt, ist sich der Kosten und Risiken von Softwarefehlern nicht bewusst.
Softwarepflege
Von Softwarepflege wird gesprochen, wenn die Software an geänderte Einsatzbedingungen, z. B. bedingt durch ein neues Betriebssystem, angepasst werden muss. Neben funktionalen Tests und obligatorischen Akzeptanztests sind dann auch die inneren Qualitätsmerkmale und nichtfunktionalen Eigenschaften wie Performance und Ressourcenbedarf in der neuen Umgebung abzusichern.
Testen nach Weiterent-
wicklung der Software
Außer den oben erwähnten Wartungsmaßnahmen sieht ein Software-Lebenszyklus oft auch eine funktionale Weiterentwicklung vor, um das Produkt wettbewerbsfähig zu halten oder den Kundenkreis zu erweitern. Neue Softwareversionen werden entwickelt. Im Zuge der Aufwandsreduktion werden Weiterentwicklungen oft mit ohnehin geplanten Wartungsmaßnahmen synchronisiert. Bei Auswahl und Design der hierbei vorzusehenden Testfälle ist natürlich besonderes Augenmerk auf die neu ergänzte Funktionalität zu richten. Im Zuge eines Regressionstests ist zu prüfen, ob die vorhandene, unveränderte Funktionalität versehentlich beeinträchtigt wurde. Je strikter die Softwarearchitektur in einem Entwicklungsprojekt von Beginn an eingehalten wurde, desto unproblematischer kann die Software in ihrem Lebenszyklus erweitert werden. In Extremfällen kann eine Neuimplementierung günstiger sein als eine Weiterentwicklung.
3.5 Testprozess und Testaktivitäten
die Tücken des unstruk-
turierten Testens
Ein gut strukturierter Testprozess mit klar aufeinanderfolgenden Testaktivitäten und definierten Schnittstellen ist eine unabdingbare Voraussetzung für effizientes Testen. Nichts ist ineffizienter, als ohne konkreten Plan »einfach mal anzufangen« mit dem operativen Testbetrieb. Die Erfahrung zeigt, dass der unstrukturierte Tester zu Beginn den Eindruck hat, schnellen Fortschritt zu machen, dann aber – auch bei hohen Aufwänden – ein gewisses Reifegrad-Level nie überschreitet. Der Test ist geprägt durch Testlücken sowie hohe ungewollte Redundanz und damit potenziell ineffizient. Das Ergebnis bleibt dann auch weit hinter einem methodischen Vorgehen zurück. Trotz schneller Anfangserfolge erfüllt der unstrukturierte Tester im Endergebnis bei vergleichbaren Aufwänden die Erwartungen nur in den seltensten Fällen. Darüber hinaus ist es häufig so, dass der Reifegradverlauf eines Softwareentwicklungsprojekts einen erratischen Charakter aufweist und in keiner Weise plan- oder prognostizierbar ist. Jederzeit ist mit teilweise dramatischen Rückschlägen in der Qualität zu rechnen – dies ist vor allem in der Endphase des Entwicklungsprojekts nicht hinnehmbar. Es ist daher essenziell, einem Testprozess zu folgen und dabei gewissen Grundregeln der Testableitung, -durchführung und -evaluierung zu folgen. Dieser Testprozess weist in der Regel einen projektspezifischen Charakter auf.
Im Folgenden wird ein generischer Testprozess mit seinen Testaktivitäten aufgezeigt. Auch wenn nicht im Detail immer exakt genauso gearbeitet werden kann, geht aus der Darstellung hervor, worüber man sich im Vorfeld Gedanken machen sollte – noch bevor der erste Test durchgeführt wird. Wie in Abb. 3-16 zu sehen, besteht ein systematischer, gut strukturierter Testprozess aus fünf Hauptaktivitäten: Testplanung, Testspezifikation, Testimplementierung, Testausführung und Testevaluierung. Von besonderer Bedeutung in der Praxis – da oft zu wenig beachtet – sind die beiden ersten Schritte.
Abb. 3-16: Übersicht Testprozess und Testaktivitäten
3.5.1 Testplanung
Die Testplanung beginnt bereits während der Systemspezifikationsphase, also während das spätere SUT selbst spezifiziert wird.
Testziele festlegen
In der Testplanung werden die wesentlichen Testziele festgelegt: Welche Qualitätseigenschaften sollen geprüft werden? Diese Testziele können z. B. aus den Qualitätsmerkmalen für Software abgeleitet werden.
Risikoeinschätzung vornehmen
Ferner ist in der Testplanung bereits eine Risikoeinschätzung für das SUT vorzunehmen. Welches Risikolevel weist das System auf? Wie sicherheitskritisch ist es?
Welche Metriken sollen
zum Einsatz kommen?
Wichtig ist auch die Vereinbarung, welche quantitativen Metriken beim Test zum Einsatz kommen sollen: Wie soll die Testüberdeckung gemessen werden, was ist das Testende-Kriterium? Hier könnte man sich z. B. eine verbleibende Fehlerfindungsrate unter einem bestimmten vorgegebenen Wert, die Überdeckung bestimmter Strukturmerkmale im Code oder die Abdeckung eines spezifizierten Anteils der Anforderungen im zugrunde liegenden Lastenheft vorstellen.
Teststrategie festlegen und
Ressourcen sicherstellen
Gegenstand der Testplanung ist aber auch die Festlegung der grundsätzlichen Teststrategie: Welche Testmethoden (von denen wir im weiteren Verlauf dieses Buchs noch viele kennen lernen werden) sollen zum Einsatz kommen? Ganz wesentlich ist auch eine Aufwandsabschätzung für den Testprozess sowie eine Termin- und Ressourcenplanung.
All dies ist festzulegen, bevor der erste Test ausgeführt wird. Nur so kann man der Gefahr entgehen, in der Endphase eines Projekts vor der vollendeten Tatsache eines Ressourcenmangels zu stehen und als einzig jetzt noch verbleibende Option den Test vorzeitig abbrechen zu müssen. Ohne vorherige Planung ist man gegen derartige Überraschungen nicht gefeit und bei Feststellung des Sachverhalts ist kein Gegensteuern mehr möglich – dies hätte früher erfolgen müssen.
Abb. 3-17: Steckbrief Testplanung
3.5.2 Testspezifikation
Die Testspezifikationsphase beginnt, sobald die Spezifikation des SUT (Lastenheft) und der Testplan zur Verfügung stehen. In dieser Phase geht es darum, abstrakte Testfälle, sog. Testspezifikationen, zu ermitteln. Diese Testspezifikationen beinhalten in aller Regel eine überwiegend nichtformale, verbale Beschreibung, wie der Test abläuft, welche Randbedingungen zu Beginn herzustellen sind und welches Sollverhalten abzuprüfen ist. Die Festlegung auf eine konkrete Testausführungsplattform erfolgt noch nicht.
Beispiel: Kaffeeautomat
Beim Test eines Kaffeeautomaten könnte man sich z. B. folgende Testspezifikation vorstellen: »Der Automat ist voll bestückt und funktionsbereit. Der Kunde wirft mindestens eine Münze ein und drückt eine Kaffeewahltaste. Der Zahlbetrag ist allerdings nicht ausreichend. Eine Kaffeeausgabe darf nicht erfolgen, der Automat wartet auf eine weitere Münzeingabe oder Betätigung der Rückgabetaste.« Dies wäre ein Test für die Anforderung im Lastenheft »Unter keinen Umständen darf eine Produktausgabe bei Unterzahlung erfolgen«. Anforderung und Testspezifikation sind einander zugehörig, die Testumgebung muss die Möglichkeit einer Referenzierung bzw. Verlinkung in geeigneter Weise unterstützen.
Tracing
Den Vorgang dieser Referenzierung assoziierter Testartefakte bezeichnet man auch als Tracing. Tracing wird z. B. eingesetzt, um Tests mit den resultierenden Testergebnissen in Verbindung zu setzen.
Testspezifikationen sind abstrakt
und implementierungsunabhängig
Testspezifikationen sind als abstrakte Testfälle zu verstehen, d. h. sie sind noch eine Vorstufe der Testimplementierung. Der Testplaner hat sich noch nicht festgelegt, wie und auf welchen Testplattformen der Test ausgeführt werden soll. Im obigen Beispiel könnte man sich vorstellen, dass bei Ausführung ein Testkunde vor dem Automaten steht und diesen bedient (eine Implementierung) oder der Mikrocontroller, auf dem die Steuerung implementiert ist, im Labor durch eine Testumgebung stimuliert wird (eine andere Implementierung). Merken wir uns, dass eine Testspezifikation mehrere Implementierungen aufweisen kann, die miteinander in Beziehung stehen.
Abb. 3-18: Steckbrief Testspezifikation
Black-Box- und White- Box-Test
In der Praxis gibt es mehrere Methoden für die Testspezifikation, zwei wichtige Vertreter sind als Black Box und White Box bekannt. Kennt oder beschreibt man bei der Testspezifikation nur das von außen beobachtbare Verhalten des SUT, also nur die Ein-/Ausgabe auf oberster Ebene, spricht man von einem Black-Box-Test. Sind auch die inneren Strukturen des SUT (z. B. der Quellcode oder ein Kontrollflussgraph) bekannt und nehmen Tests Bezug darauf, liegt ein White-Box-Test vor.
kein Test ohne Testspezifikation!
Es sei an dieser Stelle nochmals an die besondere Bedeutung der Testspezifikation hingewiesen. Da sie implementierungsunabhängig ist, besteht hier die Möglichkeit der Wiederverwendung und dadurch der Kostensenkung. Eine Testspezifikation kann jeder verstehen, ein Testprogramm nicht unbedingt, d. h. Testspezifikation und Testimplementierung können von unterschiedlichen Personengruppen durchgeführt werden. Dies gilt es bei komplexen Testaufgaben auszunutzen. Niemals sollte man den Testprozess direkt mit einer Testimplementierung beginnen, so groß die Versuchung auch sein mag.
3.5.3 Testimplementierung
Wie im Abschnitt Testspezifikation bereits ausgeführt, basieren Testimplementierungen auf Testspezifikationen, sie bilden konkrete Instanzen der allgemeineren Spezifikationen und ermöglichen damit erst die Ausführung eines Tests. Grundsätzlich können aus einer Testspezifikation mehrere Testimplementierungen hervorgehen.
eine Testspezifikation, mehrere
Testimplementierungen
Zu einer Testimplementierung gehören auch die Auswahl geeigneter Testdaten sowie die Darstellung einer konkreten, ausführbaren Testvorschrift – also der detaillierte Ablauf des Tests. Dieser kann entweder manuell, Schritt für Schritt, erfolgen oder automatisiert, indem Testskripts mit den einzelnen Testschritten ausgeführt werden. Die Testimplementierung selbst ist stark abhängig vom geplanten Testsystem und lässt sich in der Regel nicht von einer Testplattform auf eine andere übertragen.
Abb. 3-19: Steckbrief Testimplementierung
Die Implementierungsplattformen reichen hierbei von einer Abfolge manueller Fahrinstruktionen bis hin zum vollautomatisierten Testskript eines HiL-Simulators.
Neben der Festlegung der einzelnen auszuführenden Testschritte (Testvorschriften) sind auch die zur Anwendung kommenden konkreten Testdaten sowie die zu erwartenden Testergebnisse (Sollwerte) zu spezifizieren.
Ein Test ohne Kenntnis aller rele-
vanten Randbedingungen ist nutzlos.
Wichtig bei einer Testimplementierung ist die exakte technische Einstellung der Randbedingungen, die zu Testbeginn laut Testspezifikation vorliegen müssen. Ein Test ohne Kenntnis aller relevanten Randbedingungen ist nicht reproduzierbar, erlaubt keine Fehleranalyse und ist daher nutzlos!
3.5.4 Testausführung
Endlich ist es soweit: Der Test wird ausgeführt!
Schön wäre Automatisierung, unerlässlich die
Dokumentation aller Randbedingungen.
Die Phase der Testausführung beginnt mit der Verfügbarkeit des Testobjekts bzw. der Testimplementierung. Oft ist diese Phase aufgrund einer hohen Anzahl von auszuführenden Tests automatisiert. Die Testumgebung stellt die erforderlichen, spezifizierten Randbedingungen her, stimuliert das Testobjekt mit Eingangsdaten entsprechend der Testspezifikation und erfasst die Ergebnisse. Ergebnisse, Stimuli und Randbedingungen müssen lückenlos dokumentiert werden. Auf diese Weise wird die Wiederholbarkeit und Reproduzierbarkeit der Tests ermöglicht. Dies sicherzustellen, ist von besonderer Bedeutung auch im Hinblick auf die zu wartenden Regressionstests zur Absicherung von nachträglichen Codeänderungen bei Fehlerbeseitigung, Wartung oder Weiterentwicklung der Software. Diese sollte auf jeden Fall automatisiert erfolgen. Ferner wird dokumentiert, wann und durch wen der Test ausgeführt wurde.
Abb. 3-20: Steckbrief Testausführung
3.5.5 Testevaluierung
Testurteile Pass oder Fail
Bei der Testevaluierung findet der Vergleich zwischen Testergebnis und Sollwert statt. Entsprechend wird das Urteil Pass oder Fail gefällt. Defects werden im Defect-Management-System des Unternehmens eingetragen, die aus Fehlern resultierenden Fehlerkorrekturen im sog. Change-Management-System.
Defect-Management
Jeder Fehler wird nach Status, Priorität und Quelle klassifiziert und dementsprechend im Defect-Management-System dokumentiert. Am Ende dieser Phase wird ein Testbericht erstellt, der zusammenfassende, beurteilende Aussagen über den Reifegrad des Testobjekts enthält. Ferner enthält dieser Bericht oft eine Statistik über die einzelnen Fehlerklassen.
Abb. 3-21: Steckbrief Testevaluierung
3.5.6 Test- und Fehlermanagement
Verwaltung aller beim Test anfallenden
Daten, Dokumente und Artefakte
Im durchgängig alle Testphasen begleitenden Test- und Fehlermanagement werden alle testrelevanten Informationen verwaltet und abgelegt. Dazu gehört insbesondere die Verwaltung und Dokumentation des Testprozesses, der Testinfrastruktur (Testwerkzeuge und Testumgebung), aller Testprodukte bzw. beim Test anfallenden Dokumente und Artefakte, Auffälligkeiten und Fehler, Änderungen und Korrekturen. Ziel des Testmanagements ist die Unterstützung des Testprozesses mit allen Testaktivitäten und die Verwaltung aller hierbei anfallenden Daten wie Testdokumente, Richtlinien, Reviews u. Ä.
Verwaltung der Beziehung zwischen
Daten und Artefakten
Insbesondere das Change-Management und Tracing zwischen all diesen Daten wird im Rahmen des Testmanagements sichergestellt, sodass zu jedem Zeitpunkt klar ist, welche Fehlerwirkungen aktuell zu einer bestimmten Anforderung im Lastenheft auftreten oder bei welchem Test dieser Fehler entdeckt wurde.
automatische Notifikation
Von besonderer Bedeutung in der Praxis ist auch die selektive, automatisierte Notifikation aller Projektbeteiligten über gefundene Auffälligkeiten auf ihrem Weg bis zur Fehlerabstellung und Verifikation der Behebung. Hierbei kommt ein Rollenkonzept zum Tragen, z. B. müssen komponentenverantwortliche Entwickler bei jeder Fehlerzuweisung für ihre Komponente informiert werden. Sie haben dann die Möglichkeit, Stellung zu nehmen und den Status des Eintrags zu bearbeiten, insbesondere die Behebung dieses Problems zu dokumentieren, woraufhin dieser Punkt automatisch an die verifizierende Testinstanz weitergeleitet wird. Der Eintrag kann auch mit Begründung abgelehnt oder geschlossen werden, ohne dass eine Fehlerbehebung erfolgt ist. Allgemein ist es sinnvoll, die Behebung eines Fehlers durch diejenige Testinstanz verifizieren zu lassen, die den Fehlereintrag ursprünglich verfasst hatte. Nur sie kann den Eintrag schließen.
kommerzielle Werkzeuge
Viele kommerzielle Werkzeuge bieten hier Unterstützung. Zu nennen wären z. B. Micro Focus Quality Center/ALM, Tricentis Tosca Testsuite, IBM Rational Quality Manager, Polarion ALM u. a.
Abb. 3-22: Steckbrief Testmanagement
3.6 Zusammenfassung
▶Testprozesse und -methoden für Software richten sich stark nach dem zugrunde liegenden Software-Entwicklungsmodell.
▶Das bekannteste Entwicklungsmodell für Software ist das klassische V-Modell. Jede Entwicklungsstufe besitzt zwei Absicherungsprinzipien: Die Verifikation zum Test der weiteren Verfeinerung und die Validierung zum Test gegen die jeweiligen Anforderungsdokumente.
▶Software wird in verschiedenen Teststufen geprüft: Mit aufsteigender Integrationsstufe spricht man von Unit-Test, Komponententest, Integrationstest mit verschiedenen Ausprägungen, Systemtest, Produkttest, Abnahmetest und Produktionstest.
▶Testprozesse können gegliedert werden in die Aktivitäten Testplanung, Testspezifikation, Testimplementierung, Testausführung sowie Testevaluierung. Den beiden ersten Aktivitäten kommt dabei ein besonderer Stellenwert zu.
▶Vor einer Testimplementierung müssen Tests plattformunabhängig spezifiziert werden; Testspezifikationen können sich auf mehrere Testimplementierungen beziehen.
▶Alle beim Test anfallenden Artefakte und Dokumente sind miteinander zu verlinken (Tracing), z. B. ein Fehlereintrag mit dem ihn auslösenden Test und Tests mit den Anforderungen, die sie abprüfen.
▶Die Verwaltung aller Test- und Fehlerdaten sowie entsprechende Notifikations- und Verlinkungsmechanismen werden in Unternehmen oft durch den Einsatz von Test- und Fehlermanagement-Systemen umgesetzt.