e74c866773fbaf8cc29a6a0ab838659e.ppt
- Количество слайдов: 55
Vorlesung "Software-Engineering" Prof. Ralf Möller, TUHH, Arbeitsbereich STS z Vorige Vorlesung y. Analytische Qualitätssicherung y. Metriken y. Testverfahren z Heute: y. Fortsetzung: Testverfahren y. Konstruktive Qualitätssicherung 1
Einordnung Planungsphase Lastenheft Definitionsphase Pflichtenheft Entwurfsphase Anforderungs. Definition Anwendungsszenarien Abnahmetest Testfälle Grobentwurf Produktentwurf Systemtest Testfälle Feinentwurf Integrationstest Implementierungsphase Produkt, Komponenten Testfälle Modul. Implementierung Modultest Abnahme und Einführung Installiertes Produkt 2
Testverfahren: Dynamische Verfahren z Software wird mit Testdaten ausgeführt z Ausführung in realer Umgebung z Prinzip des Stichprobenverfahrens z Notwendigkeit zur Auswahl von Testfällen und Testdaten 3
Unterscheidung Testfälle - Testdaten z Testfall: yeine aus der Spezifikation oder dem Programm abgeleitete Menge von Eingabedaten zusammen mit den zugehörigen erwarteten Ergebnissen z Testdaten: y. Teilmenge der Eingabedaten der Testfälle, mit denen das Programm tatsächlich ausgeführt wird 4
Kontrollflußbezogene Verfahren (1) z Darstellung der Programm(-teile) als Kontrollflußgraphen y Anweisungen (Anweisungsblöcke) als Knoten des Graphen y Kontrollfluss als gerichtete Kanten zwischen Knoten y Zweig: Einheit aus einer Kante und den dadurch verbundenen Knoten y Pfad: Sequenz von Knoten und Kanten, die am Startknoten beginnt und am Endknoten endet x : =. . . ; y : =. . . IF x > 5 AND y < 2 THEN y : = f(x, 2) ELSE y : = g(x, 3) z : =. . . x : =. . . ; y : =. . . y : = f(x, 2) y : = g(x, 3) z : =. . . 5
Kontrollflussbezogene Verfahren (2) z Prinzip der "Überdeckung von Kontrollstrukturen" durch Testfälle (Coverage Analysis): y. Gezieltes Durchlaufen (von Teilen) der Kontrollstrukturen durch geeignete Gestaltung der Testfälle y. Angestrebter/erreichter Überdeckungsgrad in Prozent angegeben 6
Arten der Überdeckung von Kontrollstrukturen z Anweisungsüberdeckung: y Alle Anweisungen werden mindestens einmal ausgeführt z Zweigüberdeckung: y Alle Verzeigungen im Kontrollfluss werden mindestens einmal verfolgt z Bedingungsüberdeckung: y Alle booleschen Wertekonstellationen von (Teil-) Bedingungen werden einmal berücksichtigt z Pfadüberdeckung: y Durchlaufen aller Pfade von Start- zum Endknoten (außer bei sehr kleinen Programmen nur theoretisch möglich) 7
Coverage Analysis Validierung der Vollständigkeit von Testreihen anhand von Metriken Arten: l Anweisungsüberdeckung (statement coverage) -> zu schwach l Entscheidungsüberdeckung (branch coverage) -> minimum mandatory testing requirement l Pfadüberdeckung (path coverage) -> in der Praxis nicht durchführbar
Datenflußbezogene Verfahren (1) z Erweiterung der Kontrollflußgraphen um Datenflüsse z Unterscheidung verschiedener Situationen hinsichtlich des Zugriffs auf Variablen im Programm: y. Definition von Variablenwerten (Wertzuweisung) y. Berechnende Benutzung (zur Ermittlung eines Wertes in Ausdrücken) y. Prädikative Benutzung (Auswertung der Bedingungen in bedingten Anweisungen oder Schleifen) 9
Datenflußbezogene Verfahren (2) z Prinzip des Verfahrens: y. Für jeden Definitionsknoten werden definitionsfreie Pfade zu allen Benutzungsknoten ermittelt y. Die Auswahl der Testdaten muß das Durchlaufen jedes identifizierten definitionsfreien Pfades sicherstellen 10
Datenflußbezogene Verfahren (3) z Definition von drei Funktionen als Basis der Datenflußverfahren: y Funktion def bildet jeden Knoten auf die Menge der darin global definierten Variablen ab y Funktion c-use ordnet jedem Knoten die in ihm berechnend benutzten Variablen zu y Funktion p-use weist jeder Kante die Menge von Variablen zu, deren prädikative Auswertung zum Durchlaufen der Kante notwendig ist z Definition der Menge du(v, ni ), wobei v Î def(ni): y du(v, ni) enthält alle Knoten nj mit v Î c-use(nj) y alle Kanten (nk , nl) mit v Î p-use((nk, nl)), wobei ein Pfad von ni nach nj bzw. nl existiert, auf dem v nicht neu definiert wird z All-uses-Kriterium zur Auswahl von Testfällen y Für jeden Knoten und jede Variable v Î def(ni) wird mindestens ein definitionsfreier Pfad von ni zu allen Elementen von du(v, ni) ausgeführt. 11
Funktionale Verfahren z Überprüfung der in der Spezifikation festgelegten Funktionalität y Programmstruktur irrelevant y Beste Grundlage: formale Spezifikation z Bestimmung der Testdaten: y Bildung "funktionaler Äquivalenzklassen": Eingabe- und Ausgabemengen, die jeweils zu einer (Teil-) Funktionalität gehören y Alle Werte einer Äquivalenzklasse verursachen ein identisches funktionales Verhalten eines Programms z Auswahl von Testdaten aus den Äquivalenzklassen: y Zufällig y Test spezieller Werte (z. B. 0, nil) y Grenzwertanalyse (primär Grenzbereiche der Eingabemengen als Testdaten) 12
Testen von Moduln z Aufdecken von Fehlern in der isolierten Modulrealisierung z Modultest wird meist als Teilphase der Implementierung betrachtet z Notwendigkeit einer Testumgebung, die anderen Module simuliert und das Modul selbst benutzbar macht (Fehler in Testumgebung? ) 13
Testumgebungen z (Wiederholten) Aufruf des Testobjektes ermöglichen z Eingabedaten für Testobjekt bereitstellen z Externe Ressourcen und deren Ergebnisse/Aktivitäten simulieren (z. B. importierte Module) z Ergebnisse der Testausführung ausgeben und speichern 14
Testen von Modulverbindungen z Testen von Subsystemen (= Teilmengen von verknüpften Moduln) z Prüfung der Kommunikation zwischen den Moduln z Schrittweiser Aufbau größerer Subsysteme durch Hinzufügen weiterer Module/Subsysteme (inkrementelles Testen, Integrationstest) z Ausführung meist Bottom-up, jedoch auch Top-Down -Vorgehensweise möglich z Ebenfalls Testumgebung notwendig, "Stub"-Moduln bzw. Treiber-Moduln erforderlich 15
JUnit z Framework, um den Unit-Test eines Java. Programms zu automatisieren. z einfacher Aufbau z leicht erlernbar Many thanks to Carrara Engineering for making their slides available: http: //www. carrara. ch/cspb/html/Tools/JUnit/ 16
Konstruktiver Ansatz z Testfälle werden in Java programmiert, keine spezielle Skriptsprache notwendig. z Idee ist inkrementeller Aufbau der Testfälle parallel zur Entwicklung. y. Pro Klasse wird mindestens eine Test-Klasse implementiert. 17
Simple Test Case [1/2] public class Money { private double amount; public Money(double amount) { this. amount = amount; } public double get. Amount () { return amount; } } 18
Simple Test Case [2/2] import junit. framework. *; public class Money. Test extends Test. Case { public Money. Test(String name) { super(name); } public void test. Amount() { Money money = new Money(2. 00); assert. Equals("err-msg", 2. 00, money. get. Amount()); } } public static void main(String[] args) { junit. swingui. Test. Runner. run(Money. Test. class); } 19
Anatomie eines Testfalls [1/3] z Jede Testklasse wird von der Framework. Basisklasse junit. framework. Test. Case abgeleitet. z Jede Testklasse erhält einen Konstruktor für den Namen des auszuführenden Testfalls. 20
Anatomie eines Testfalls [2/3] z JUnit erkennt die Testfälle anhand des Signaturmusters public void test. XXX() z Das Framework kann mit dem Java-Reflection. Package die Testfälle somit automatisch erkennen. 21
Anatomie eines Testfalls [3/3] z Die assert. Equals Methode dient dazu, eine Bedingung zu testen. z Ist eine Bedingung nicht erfüllt, d. h. false, protokolliert JUnit einen Testfehler. z Der junit. swingui. Test. Runner stellt eine grafische Oberfläche dar, um die Test kontrolliert ablaufen zu lassen. 22
Das JUnit-Framework 23
Assert [1/4] z Die Klasse Assert definiert eine Menge von assert Methoden, welche die Testklassen erben. z Mit den assert Methoden können unterschiedliche Behauptungen über den zu testenden Code aufgestellt werden. z Trifft eine Behauptung nicht zu, wird ein Testfehler protokolliert. 24
Assert [2/4] z asser. True (boolean condition) verifiziert, ob einen Bedingung wahr ist. z assert. Equals(Object expected, Object actual) verifiziert, ob zwei Objekte gleich sind. Der Vergleich erfolgt mit der equals Methode. z assert. Equals(int expected, int actual) verifiziert, ob zwei ganze Zahlen gleich sind. Der Vergleich erfolgt mit dem == Operator. z assert. Null(Object object) verifiziert, ob einen Objektreferenz null ist. 25
Assert [3/4] z assert. Equals(double expected, double actual, double delta) verifiziert, ob zwei Fliesskommazahlen gleich sind. Da Fliesskommazahlen nicht mit unendlicher Genauigkeit verglichen werden können, kann mit delta ein Toleranzwert angegeben werden. z assert. Not. Null(Object object) verifizert, ob eine Objetkreferenz nicht null ist. Es existieren überladene Methoden mit einer Zeichenkette als erstem Argument für die Angabe der Fehlermeldung im Protokoll. 26
Assert [4/4] z assert. Same(Object expected, Object actual) verifizert, ob zwei Referenzen auf das gleiche Objekt verweisen. z Für die primitiven Datentypen float, long, boolean, byte, char und short existieren ebenfalls assert. Equals Methoden. 27
Testen von Exceptions [1/2] z Exceptions werden in Java mit dem catch Block behandelt. z Mit der Methode fail aus der Assert Klasse wird ein Testfehler ausgelöst und protokolliert. 28
Testen von Exceptions [2/2] z Im vorliegenden Beispiel wird beim Aufruf des Konstruktors der Klasse My. Class mit einer negativen Zahl die Illegal. Argument. Ecxeption ausgelöst. try { new My. Class(-10); fail(“Meine Meldung im Fehlerfall“); catch (Illegal. Argument. Exception e) { } } 29
Test. Fixture [1/2] z Ein Testfall sieht in der Regel so aus, dass einen bestimmte Konfiguration von Objekten aufgebaut wird, gegen die der Test läuft. z Diese Menge von Testobjekten wird auch als Test-Fixture bezeichnet. z Damit fehlerhafte Testfälle nicht andere Testfälle beeinflussen können, wird die Test-Fixture für jeden Testfall neu initialisert. 30
Test. Fixture [2/2] z In der Methode set. Up werden Instanzvariablen initialisiert. z Mit der Methode tear. Down werden wertvolle Testressourcen wie zum Beispiel Datenbank- oder Netzwerkverbindungen wieder freigegeben. 31
Beispiel Test. Fixture import junit. framework. *; public class Money. Test extends Test. Case { private Money money; . . . protected void set. Up() { money = new Money(2. 00); } protected void tear. Down() { } public void test. Amount() { assert. True("err-msg", 2. 00 == money. get. Amount()); }. . . 32
Lebenszyklus eines Testfalls z Testklasse Money. Test mit Methoden test. Adding und test. Amount. y y y y new Money. Test(“test. Adding“) set. Up() test. Adding() tear. Down() New Money. Test(“test. Amount“) set. Up() test. Amount() tear. Down() 33
Test. Suite [1/5] z Um eine Reihe von Tests zusammen ausführen zu können, werden die Tests zu Test. Suites zusammengefasst. z Eine Suite von Test wird dabei durch ein Test. Suite Objekt definiert. z Mit JUnit können beliebig viele Test in einer Test. Suite zusammengefasst werden. 34
Test. Suite [2/5] z Um eine Testsuite zu definieren, ist ein Test. Suite Objekt zu bilden und mittels der add. Test. Suite Methode verschiedene Testfallklassen hinzuzufügen. z Jede Testfallklasse definiert implizit eine eigene suite Methode, in der alle Testfallmethoden der betreffenden Klasse eingebunden werden. [Reflection Package] 35
Test. Suite [3/5] import junit. framework. *; public class All. Tests { public static Test suite() { Test. Suite suite = new Test. Suite(); suite. add. Test. Suite(Money. Test. class); suite. add. Test. Suite(Formater. class); suite. add. Test. Suite(Test. Sheet. class); return suite; } } 36
Test. Suite [4/5] z Damit beliebig viele Test. Case und Test. Suite Objekte zu einer umfassenden Test. Suite. Hierarchie kombiniert werden kann, wird das Composite. Pattern verwendet. 37
Test. Suite [5/5] z In vielen Fällen ist es praktisch, pro Package eine Test. Suite-Klasse zu definieren. z Es hat sich eingebürgert diese Klasse All. Test zu nennen. 38
Beispiel All. Tests – Einbindung von Test-Klassen package com. iq. html. Formatter; import junit. framework. *; public class All. Tests { public static Test suite() { Test. Suite suite = new Test. Suite("html. Formatter"); suite. add. Test. Suite(Spacer. Test. class); suite. add. Test. Suite(Level. Test. class); return suite; } } public static void main (String[] args) { junit. swingui. Test. Runner. run(All. Tests. class); } 39
Beispiel All. Tests – Einbindung von All. Tests-Klassen package com. iq. html; import junit. framework. *; public class All. Tests { public static Test suite() { Test. Suite suite = new Test. Suite("Package html"); suite. add. Test(com. iq. html. tag. All. Tests. suite()); return suite; } } public static void main (String[] args) { junit. swingui. Test. Runner. run(All. Tests. class); } 40
Testausführung z In vielen Fällen ist es praktisch, pro All. Tests Klasse eine main Methode zu definieren, welche die graphische Benutzeroberfläche aufruft und die eigene Klasse als Parameter übergibt. public static void main (String[] args) { junit. swingui. Test. Runner. run(All. Tests. class); } 41
Zusammenfassung z Junit y. Einfaches Framework für den Unit-Test von Java. Programmen. y. Testfälle werden parallel zum eigentlichen Code entwickelt. y. Die Tests können vollautomatisch ausgeführt werden. 42
Qualitätssicherung durch Tests z Ein Test ist prinzipiell nur geeignet, evtl. vorhandene Fehler eines Systems zu Tage treten zu lassen, nicht jedoch die Abwesenheit von Fehlern zu zeigen (vgl. Verifikation) z Der Überdeckungsgrad ist ein Maß für den Grad der Vollständigkeit eines Tests z Ein Regressionstest ist ein Testverfahren, bei dem eine Sammlung von Testfällen erstellt wird, die bei Änderungen am System (automatisch) erneut überprüft werden z Bei einer Individualsoftware findet ein Abnahmetest statt z Beim Alpha-Test für Standardsoftware wird das System in der Zielumgebung des Herstellers durch ausgewählte Anwender erprobt z Beim Beta-Test für Standardsoftware wird das System bei ausgewählten Zielkunden in einer eigenen Umgebung zur Probenutzung zur Verfügung gestellt. Auftretende Probleme und Fehler werden protokolliert. Beta-Tester erhalten typischerweise einen Preisnachlaß auf das endgültige Produkt. Typischerweise werden Beta-Tests iterativ mit aufeinanderfolgenden "release candidates" (RC) durchgeführt. 43
Testen: Zusammenfassung z Rolle der Spezifikation beim Test z Testsystematik z Reproduzierbarkeit von Tests (insbesondere nach Änderungen) z Tests decken Fehler auf z Tests helfen nicht, Fehler zu vermeiden z Herstellungsprozeß bedeutsam: -> Qualitätsmanagement, konstruktive Verfahren 44
Konstruktive Verfahren z Annahme: Die Qualität eines Produktes wird maßgeblich durch die Qualität des Herstellungsprozesses bestimmt y. Qualität ins Bewußtsein der Projektmitglieder bringen y. Rückverfolgbarkeit gewährleisten y. Verantwortlichkeiten und Zuständigkeiten schaffen (Planstellen) y-> Organisatorischen Rahmen für Software-Herstellungsprozeß schaffen 45
ISO 9000 (erstmals standardisiert 1987) z Das ISO 9000 Normenwerk legt für ein Auftraggeber-Lieferanten-Verhältnis einen allgemeinen, übergeordneten, organisatorischen Rahmen zur Qualitätssicherung von Produkten (insbesondere ISO 9001). z Geprägt durch industrielle Fertigung von Produkten, aber ausgeweitet auf Erstellung von Software (9000 -3) z Zertifizierung nach 9001 bzw. 9000 -3 durch Zertifizierungsstelle, wenn ein Qualitäts-managementsystem vorhanden. z Zertifiziert wird der Herstellungsprozeß, NICHT DAS PRODUKT 46
ISO 9000 - Struktur (1) [Balz 98] 47
ISO 9000 - Struktur (2) [Balz 98] 48
ISO 9000 -3 z Aufbau ISO 9000 -3: y Rahmen y Lebenszyklustätigkeiten y Unterstützende Tätigkeiten z Inhalt ISO 9000 -3: y Entwicklung y Lieferung y Wartung von Software z Maßnahmen: y der Geschäftsführung y der Mitarbeiter der Qualitätssicherung z Anwendungsformen: y Darlegung der Qualitätssicherung gegenüber Dritten y Aufbau und Verbesserung eines QS-Systems 49
ISO 9000 -3 - Implizites Vorgehensmodell [Balz 98] 50
ISO 9000 -3 - Implizites Vorgehensmodell [Balz 98] 51
ISO 9000 -3 - Implizites Vorgehensmodell z Phasenunabhängige Tätigkeiten: y Konfigurationsmanagement: x Identifikation und Rückverfolgbarkeit d. Konfiguration x Lenkung von Änderungen x Konfigurations-Statusbericht y Lenkung der Dokumente y Qualitätsaufzeichungen y Messungen und Verbesserungen: x am Produkt x des Prozesses y Festlegung von Regeln, Praktiken und Übereinkommen für den Einsatz eines Qualitätsmanagementsystems y Nutzung von Werkzeugen und Techniken, um QS-Leitfaden umzusetzen y Unterauftragsmanagement 52
ISO 9000 - Bewertung z Vorteile: z Aufmerksamkeit auf Qualitätssicherung z Externe Zertifizierung und Wiederholung d. Audit z Festlegen von Anforderungen z Erleichtert die Akquisition von Aufträgen z Weniger Produkthaftungsrisiko z Stärkung Qualitätsbewußtsein z Nachteile: z Unsystematischer Aufbau z Keine sauber Trennung zwischen fachlichen, Management- und QSAufgaben z Gefahr Software-Bürokratie z Gefahr mangelnde Flexibilität z Hoher Aufwand für Einführung und Pflege 53
Andere Modelle z TQM (Total Quality Management) z CMM (Capability Maturity Model) z SPICE (Software Process Improvement and Capability d. Etermintation) z Siehe: Balzert, Lehrbuch der Softwaretechnik Band 2 54
Was kommt beim nächsten Mal? 55
e74c866773fbaf8cc29a6a0ab838659e.ppt