http://www.constructionphotography.com Einfaches Programmtesten OOPM, Ralf Lämmel
Naives Testen versus systematisches Testen (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 76
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 77 Naives Testen von ggt public class Functionality { public static int gcd(int x, int y) { while (x!= y) { if (x > y) x = x - y; else y = y - x; } return x; } public static void main(string[] args) { System.out.println(gcd(6,5)); // 1 System.out.println(gcd(6,4)); // 2... } } Sind damit alle Fälle getestet? Wie wird dies kontrolliert?
Beispielecode zu dieser Vorlesung (Komplette Eclipse-Projekte) http://svn.code.sf.net/p/developers/code/repository/oopm/eclipse/ simpletest/ (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 78
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 79 Charakteristik des naiven Testens Ausführen von Tests in main() Methode. Ausgabe der Ergebnisse auf System.out. Manuelles Begutachten der Ergebnisse. u.u. unsystematische Auswahl der Testdaten. u.u. Überschreibung der Testfälle für neue Tests.
Systematisches Testen von ggt Import von Test- Methoden Werfe Ausnahme, wenn Werte nicht gleich Programmierte Testfälle (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau import static org.junit.assert.*;! public class Functionality { public static int gcd(int x, int y) {... } public static void main(string[] args) { assertequals(1, gcd(6,5)); assertequals(2, gcd(6,4));... } } Erwarteter Wert 80 Tatsächlicher (berechneter) Wert
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 81 Grundsätzliche Begriffe zum Testen SUT: System Under Test Testfall = Eingabedaten + erwartete Ausgabe (e) Testfallausführung Ermittlung der tatsächliche Ausgabe (t) Erfolgreicher Testfall: e und t stimmen überein. Gescheiterter Testfall: e und t stimmen nicht überein. Test-Treiber Programm zum Ausführen der Testfälle Protokollierung der Testergebnisse
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 82 Programmierung von Testfällen mittels Assert-Methoden assertequals(long expected,long actual) assertequals(double expected,double actual,double delta) asserttrue(<condition>) assertfalse(<condition>)... Reihenfolge beachten!
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 83 If it s not tested, it s broken! Compiler / IDE überprüft Syntax- und Typkorrektheit. Tests helfen bei funktionaler Korrektheit. Anforderungen für Tests: dokumentiert ausführbar seiteneffekt-frei unabhängig abdeckend...
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 84 Was kann Testen leisten? Erhöhung des Vertrauens in Korrektheit Verbindliche Form von Dokumentation Ausführen aller Programmteile Aufdeckung problematischer Änderungen
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. Was kann Testen nicht leisten? Beweis funktionaler Korrektheit. Beweis der Abwesenheit von Fehlern. Beweis der Übereinstimmung zwischen erwartetem Verhalten und Edsger Wybe Dijkstra *1930 2002 getestetem Verhalten Program testing can be used to show the presence of bugs, but never to show their absence (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 85
Methoden zum systematischen Testen (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 86
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 87 Granularitätsstufen für das Testen Unit-Test Integrationstest Anwendungstest http://www.goethe-verlag.com/book2/en/ende/ende070.htm
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 88 Granularitätsstufen für das Testen Unit-Test Integrationstest Anwendungstest Testen der vollständigen Anwendung in der Zielumgebung Akzeptanztest zur Erfüllung aller Anforderungen Regressionstest zum Vergleich zwischen zwei Versionen Last-Test zum (Zeit-) Verhalten unter einer gewissen Last Verantwortlich: Auftraggeber, Entwickler
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 89 Granularitätsstufen für das Testen Unit-Test Integrationstest Test des Zusammenspiels von Modulen einer Anwendung Teile der Umgebung simuliert Verantwortlich: Entwickler Anwendungstest
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 90 Granularitätsstufen für das Testen Unit-Test Test einzelner Module ( Test im Kleinen ) Paket Klasse Methode Wir konzentrieren uns vorerst auf das Testen von Methoden. Verantwortlich: Entwickler Integrationstest Anwendungstest
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 91 Glassbox-Testen Struktur-Testen Ableiten der Testfälle aus dem Code. Überdeckung (Coverage) von allen Anweisungen allen Zweige http://en.wikipedia.org/wiki/code_coverage allen Teilbedingungen allen Pfaden
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 92 Glassbox-Testen int foo(int x, int y)! {! int z = 0;! if ((x>0) && (y>0)) {! z = x;! } }! return z;! Erreichen wir den Then-Zweig? Erschöpfen wir die Möglichkeiten für Wahrheitswerte? http://en.wikipedia.org/wiki/code_coverage
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 93 Glassbox-Testen Funktionsüberdeckung! Definition: Alle Funktionen werden aufgerufen. Beispiel: Jeglicher Aufruf von foo.
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 94 Glassbox-Testen Anweisungsabdeckung! Definition: Alle Anweisungen werden ausgeführt. Beispiel: foo(1,1) Gegenbeispiel: foo(0,0) int foo(int x, int y)! {! int z = 0;! if ((x>0) && (y>0)) {! z = x;! }! return z;! }
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 95 Glassbox-Testen Zweigüberdeckung! Definition: Alle Zweige werden getestet. Beispiel: foo(1,1) foo(0,1) int foo(int x, int y)! {! int z = 0;! if ((x>0) && (y>0)) {! z = x;! }! return z;! }
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 96 Glassbox-Testen Bedingungsüberdeckung! Definition: Alle Teilbedingungen werden wahr und falsch. Beispiel: foo(1,1) foo(1,0) foo(0,0) int foo(int x, int y)! {! int z = 0;! if ((x>0) && (y>0)) {! z = x;! }! return z;! }
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 97 Blackbox-Testen Funktionales Testen Ableiten der Testfälle aus der Spezifikation. Spezifikation des Verhaltens WAS tut eine Methode? Überdeckung von Normalfällen Fehlerfällen Grenzfällen Wir konzentrieren uns vorerst auf das Testen von Normalfällen. Codeüberdeckung nicht notwendig vollständig.
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 98 Spezifikation von ggt Eingabe: x, y positive ganze Zahlen Ausgabe: z positive ganze Zahl Eigenschaft über x, y, z: z ist ein Teiler von x und y. Für jeden anderen Teiler z gilt dass z < z.
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 99 Anforderungen an Spezifikation Natürlichsprachlich, semiformal oder formal Eindeutig Präzise Korrekt Vollständig In der Praxis sind diese Anforderungen möglicherweise zu teuer. Allerdings helfen Tests auch als Form der Spezifikation. Widerspruchsfrei Wir werden uns später intensiver mit Spezifikationen beschäftigen.
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 100 Klassifizierung von Testfällen Momentaner Fokus Normalfälle Grenzfälle Fehlerfälle Testen aller Fälle ist typischerweise nicht möglich. Man bildet dann Äquivalenzklassen. Man kann ebenfalls zufällige Testdaten anwenden.
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 101 Normalfälle für ggt 1. Argument kleiner als 2. Argument 2. Argument kleiner als 1. Argument 1. Argument gleich zu 2. Argument 1. Argument ein Vielfaches vom 2. Argument 1. Argument nicht ein Vielfaches vom 2. Argument
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 102 Fehlerfälle Die Erwartung ist hier, dass das Programm definiertes Verhalten in den Fehlersituationen zeigt. Argument ausserhalb des Definitionsbereiches z.b. ggt von 0 und 1 Vorbedingung einer Methode nicht erfüllt z.b. Entfernen des Kopfelementes aus leerer Liste Wir werden später besondere Programmiertechniken besprechen, um erwartete Fehler ( Ausnahmen ) als erwartete Ergebnisse zu programmieren.
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger s OOPM 2008 Vorlesung zum Testen zurück. (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 103 Grenzfälle Die Hypothese ist hier, dass das Programm eventuell an den Grenzen versagt. Grenzen des Definitionsbereichs Leere Liste (wenn nicht schon Fehlerfall) Null (wenn nicht schon Fehlerfall) Ein-elementige Liste Operationen am Anfang/am Ende von Listen Eine nicht erzielbare Genauigkeit
Der logistische Ansatz zur Lösung, Abgabe und Kontrolle der Programmier(haus)aufgaben Beinhaltet einfaches Testen! (C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 104
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 105 Schritte auf Seite des Studierenden Studierender holt die Aufgabe über svn ab. Studierender kopiert das Verzeichnis (z.b. 1 für die erste Aufgabe in das persönliche OOPM-Verzeichnis für Lösungen ( solutions ). Studierender löst die Programmieraufgabe: Anpassung von Datei Functionality.java Passieren der Tests in Datei PublicTests.java Studierender löst Hausaufgabe: Ersetzen von Datei Hausaufgabe.pdf durch Lösung. Studierender reicht Verzeichnis mit Lösung über svn ein. Im Prinzip reicht Functionality.java (und Hausaufgabe.pdf), aber zur Sicherheit sollte man das gesamte Eclipse-Projekt einreichen.
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 106 Architektur der Programmier(haus)aufgaben Vorgabe einer Klasse Functionality.java Methodensignaturen der Aufgabe Methodenkörper sind unvollständig oder fehlen Vorgabe einer Klasse PublicTests.java main-methode enthält Testfälle mittels assert Initial: Werfen einer Ausnahme Bei Abgabe: Kein Werfen Geheimhaltung einer Klasse ExtraTests.java
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 107 Verwendung von geheimen Tests Extra Tests für ggt import static org.junit.assert.*; Damit kann bei der! Kontrolle wirksam die public class ExtraTests { Korrektheit bzw. public static void main(string[] args) { Vollständigkeit der! Lösung überprüfen. // swap arguments assertequals(4, Functionality.gcd(8,12));! // bigger numbers assertequals(25, Functionality.gcd(175,25));! // much bigger numbers assertequals(64, Functionality.gcd(1024,192)); } }
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 108 Weitere Regeln für die Aufgaben ( subject to change ) Ganze Eclipse-Projekte einreichen. Das Eclipse-Projekt muss funktionieren as is. UTF-8 encoding in Eclipse einstellen. Eclipse-Versionen Kepler oder Luna verwenden. JUnit 4 (nicht 3) verwenden. Code nur begrenzt anpassen. Package, Klassen- und Methodennamen bewahren Methodensignaturen bewahren Nur fehlende Bereiche von Functionality.java ausfüllen.
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 109 Schritte bei der Aufgabekontrolle auf Seiten des OOPM-Teams Automatisches Kompilieren von Functionality.java u.a. Automatisches Ausführen von PublicTests.java auf Lösung. Automatisches Ausführen von ExtraTests.java auf Lösung. Automatische Klonerkennung ( Betrugskontrolle ) Automatische Metrikbestimmung ( besondere Lösungen ) Manuelle Würdigung des Codes. Manuelle Bewerbung der Hausaufgabe.
(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau Zusammenfassung Unit-Testen der funktionalen Korrektheit Programmierung mit asserts in Java Nicht behandelt: Anwendungs- und Integrationstesten Last-Testen zu Ressourcen Akzeptanz-Testen GUI-Testen... Ausblick Numerische Algorithmen Programmierung mit Feldern