Testen von Programmen
OOPM, Ralf Lämmel
Naives Testen versus
systematischeres Testen
Ausgewählter Beispielcode für die Vorlesung:
http://svn.code.sf.net/p/developers/code/repository/oopm/eclipse/simpletest/
Naives Testen von ggT
Wie wird dies kontrolliert?
Sind damit alle Fälle getestet?
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 ...
}
}
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.
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 ...
}
}
Systematischeres Testen von ggT
Tatsächlicher (berechneter) Erwarteter Wert
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));
...
} }
Werfe
Ausnahme, wenn Werte nicht gleich Import von Test-
Methoden
Programmierte
Sind damit alle
Fälle getestet?
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
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.
Compiler / IDE überprüft Syntax- und Typkorrektheit.
Tests helfen bei funktionaler Korrektheit.
Anforderungen für Tests:
dokumentiert ausführbar
seiteneffekt-frei unabhängig
abdeckend
If it´s not tested, it´s broken!
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Methoden zum
systematischen Testen
Granularitätsstufen für das Testen
Anwendungstest Integrationstest Unit-Test
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Granularitätsstufen für das Testen
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
Integrationstest
Verantwortlich: Auftraggeber, Entwickler
Unit-Test
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Granularitätsstufen für das Testen
Anwendungstest Integrationstest
Test des Zusammenspiels von Modulen einer Anwendung Teile der Umgebung simuliert
Verantwortlich: Entwickler
Unit-Test
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Granularitätsstufen für das Testen
Anwendungstest Integrationstest Unit-Test
Test einzelner Module (“Test im Kleinen”) Paket
Klasse Methode
Verantwortlich: Entwickler
Wir konzentrieren uns vorerst auf das Testen
von Methoden.
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Glassbox-Testen
Struktur-Testen
Ableiten der Testfälle aus dem Code.
Überdeckung (Coverage) von allen Anweisungen
allen Zweige
allen Teilbedingungen allen Pfaden
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
http://en.wikipedia.org/wiki/Code_coverage
int foo(int x, int y) {
int z = 0;
if ((x>0) && (y>0)) { z = x;
}
return z;
}
Erreichen wir den Then-/Else-
Zweig?
Erschöpfen wir die Möglichkeiten für
Wahrheitswerte?
Glassbox-Testen
Definition:
Alle Funktionen werden aufgerufen.
Beispiel:
Jeglicher Aufruf von foo.
Glassbox-Testen
Funktionsüberdeckung
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;
}
Glassbox-Testen
Anweisungsabdeckung
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;
Glassbox-Testen
Zweigü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;
}
Glassbox-Testen
Bedingungsüberdeckung
Brauchen wir alle 3?
Funktionales Testen
Ableiten der Testfälle aus der Spezifikation.
Überdeckung von
Normalfällen — Validen Eingaben Fehlerfällen — Fehlerhafte Eingabe
Grenzfällen — Grenzwertige Eingaben Codeüberdeckung nicht notwendig vollständig.
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Wir konzentrieren uns vorerst auf das Testen von Normalfällen.
Blackbox-Testen
Etwa Vor- und
Nachbedingungen
Klassifizierung von Testfällen beim Blackbox-Testen
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.
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
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.
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
…
Anforderungen an Spezifikationen
Natürlichsprachlich, semiformal oder formal Eindeutig
Präzise Korrekt
Vollständig
Widerspruchsfrei
In der Praxis sind diese
Anforderungen möglicherweise zu
“teuer”. Allerdings taugen Tests auch als Form der Spezifikation.
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Wir werden uns später intensiver
Fehlerfälle
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
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Wir werden später besondere Programmiertechniken besprechen, um erwartete Fehler („Ausnahmen“) als
erwartete Ergebnisse zu „programmieren“.
Die Erwartung ist hier, dass das Programm ein
definiertes Verhalten in den
Fehlersituationen zeigt.
Grenzfälle
Grenzen des Definitionsbereichs
„Null“ (wenn nicht schon Fehlerfall)
Null-elementige Liste (wenn nicht schon Fehler- oder Normalfall) Ein-elementige Liste
Operationen am Anfang/am Ende von Listen Eine u.U. nicht erzielbare Genauigkeit
…
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Die Hypothese ist hier, dass das Programm
eventuell an den
Grenzen versagt.
Javadoc-basierter Kommentar zur Spezifikation
/**
* @param m first operand of addition (non-negative) * @param n second operand of addition (non-negative) * @return the sum of the two operands
*/
public static int add(int m, int n) { return m==0 ? n : add(m-1,n)+1;
}
Was passiert für negative Operanden?
Die Spezifikation ist also nicht vollständig.
Javadoc-basierter Kommentar zur Spezifikation (Überarbeitung)
/**
* @param m first operand of addition (non-negative) * @param n second operand of addition
* @return the sum of the two operands
* @throws java.lang.StackOverflowError if m is negative */
public static int add(int m, int n) { return m==0 ? n : add(m-1,n)+1;
}
Negative Operanden sind nun erklärt.
Bestandteile einer Methodenspezifikation
Vorbedingung
Eingabeparameter Nachbedingung
Ergebnis
Ausnahmen / Fehler Seiteneffekte
...
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
z.B.: Argument amount ist positiv.
z.B.: balance ist um amount erhöht.
Testen mit JUnit
Ein naiver Testfall
public class PrimitiveRecursive {
public static int add(int m, int n) { return m==0 ? n : add(m-1,n)+1;
}
public static void main(String[] args) {
System.out.println(add(42,46)); // prints 88 }
}
Erwartetes Ergebnis Zu testende
Berechnung
import org.junit.Test;
import static org.junit.Assert.*;
public class TestPrimitiveRecursive {
@Test
public void testAddNormal1() {
assertEquals(88,PrimitiveRecursive.add(42,46));
} }
Import der JUnit- Funktionalität
Hilfsklasse zur Aufbewahrung von Testfällen Markierung
der Testfall- Methode
Erwartetes Ergebnis
Zu testende Berechnung
Systematischer Testfall mit JUnit
Ausführen von JUnit-Tests
“Grün” bedeutet,
dass alle Tests
Systematisches Testen
mit dem JUnit-Framework
http://junit.org
Automatisierung von Unit-Tests in Java Sehr gute Tool-Unterstützung bei
Erstellung Ausführung
Protokollierung
Testausführung auf Knopfdruck
Kent Beck
Erich Gamma
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Markierung von Methoden durch Java-Annotations
@Test
Testmethode mit Assertions
@Before
Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten)
@After
Ausführung nach jeder Testmethode ...
Ausführung der markierten Methoden über Java-Reflection
JUnit-Annotationen
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Mehr JUnit-Assert-Methoden
assertEquals(int expected,int actual)
assertEquals(double expected,double actual,double delta) assertEquals(Object expected, Object actual)
assertTrue(<condition>) assertFalse(<condition>) assertNull (Object o)
assertNotNull(Object o)
assertSame(Object expected, Object actual)
assertNotSame(Object expected, Object actual)
Reihenfolge beachten!
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Mehr JUnit-Beispiele
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Fehlerfall zur Addition
@Test(expected=java.lang.StackOverflowError.class) public void testAdd1stNegative() {
PrimitiveRecursive.add(-1,0);
}
Dokumentation der erwarteten
Ausnahme für den Fehlerfall
Fehlerfall zum MergeSort
@Test(expected=java.lang.NullPointerException.class) public void testMergeSortWithNull() {
mergeSort(null);
}
Dokumentation der erwarteten
Ausnahme für den Fehlerfall
Alternative:
Grenzfall zum MergeSort
public void testMergeSortWithNull() { int[] x = null;
mergeSort(x);
assertNull(x);
}
Fehlerfälle zum ggT
Dokumentation der erwarteten Ausnahme für den Fehlerfall
@Test(expected=java.lang.ArithmeticException.class) public void testGcdOf1and0() {
IterativeMod.gcd(1,0);
}
@Test(expected=java.lang.ArithmeticException.class) public void testGcdOf0and1() {
IterativeMod.gcd(0,1);
}
Grenzfälle
Operationen am Anfang/am Ende von Listen und Feldern
“Null” falls dies nicht ohnehin ein Fehlerfall ist Eine nicht erzielbare Genauigkeit
Grenzen des Definitionsbereichs Einzelnes Element
Leere Eingabe
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.
Grenzfälle für lineare Suche
public class TestLinear {
public static int[] a = {1,2,3,4,5,6,7,9,10};
@Test
public void testFirst() {
assertEquals(0,Program.linear(a, 1));
}
@Test
public void testLast() {
assertEquals(8,Program.linear(a, 10));
} ...
}
Das sind 9 Werte auf den
Indizes 0--8.
Normalfälle für lineare Suche
public class TestLinear {
public static int[] a = {1,2,3,4,5,6,7,9,10};
@Test
public void testSecond() {
assertEquals(1,Program.linear(a, 2));
}
@Test
public void testMissing() {
assertEquals(-1,Program.linear(a, 8));
} ...
}
Fakultätsfunktion
/**
* @param n non-negative operand * @return factorial (1 * ... * n) */
public static int factorial(int n) { int r = 1;
for (int i=1; i <= n; i++) r *= i;
return r;
}
Normalfälle für Fakultätsfunktion
@Test
public void testFactorialOf1to4() { assertEquals(1, factorial(1));
assertEquals(2, factorial(2));
assertEquals(6, factorial(3));
assertEquals(24, factorial(4));
}
Grenzfall oder Normalfall?
@Test
public void testFactorialOf0() { assertEquals(1, factorial(0));
}
Aus programmiertechnischer Sicht
könnte dies als Grenzfall gelten.
Fehlerfall zur Fakultätsfunktion
@Test
public void testFactorialForNegativeOperand() { assertEquals(1, factorial(-1));
}
Beachte: Fehlerfälle können auf verschiedene Arten
und Weisen behandelt werden: Ausnahmen,
Boolesche Werte oder ‚normale‘ Ergebnisrückgabe.
Grenzfall zur Fakultätsfunktion
@Test
public void testFactorialWithRangeError() { assertEquals(-288522240, factorial(17));
}
Beachte: Es ist wichtig, zu versuchen alle Grenzfälle auszumachen. Im konkreten Fall wäre
es denkbar, dass die Funktion anders reagiert.
Mehr Beispiele für das Testen
Fakultät
Referenzimplementation als Orakel Potenzierung
Referenzimplementation als Orakel Reihentwicklung für Sinus
Genauigkeitsschranken für Vergleich Sortieralgorithmen
Erschöpfende Fallunterscheidung
Türme von Hanoi
Fakultät
public class PrimitiveRecursive {
public static int factorial(int n) { return (n == 0) ?
1
: n * factorial(n-1);
} }
public class TailRecursive {
public static int factorial(int n) { return factorial(1,n);
}
private static int factorial(int x, int n) { return (n==0) ? x : factorial(n*x,n-1);
} }
@Test
public void testFactorialOf0to10() { for (int i = 0; i <= 10; i++)
assertEquals( PrimitiveRecursive.factorial(i), TailRecursive.factorial(i));
Referenzimplementation
Optimierte Implementation
Test
Testen der Potenzierung
Potenzierung
(Ineffiziente Referenzimplementation)
public static int power(int x, int n) { int result = 1;
for (int i=1; i<=n; i++) result *= x;
return result;
}
Potenzierung
(Effizientere Implementation)
public static int power(int x, int n) { int k = n;
int p = x;
int y = 1;
while (k>0)
if (k % 2 == 0) { p = p * p;
k = k / 2;
}
else {
y = y * p;
k = k - 1;
}
return y;
Testen mittels Referenzimplementation
public class TestEfficient {
@Test
public void testNormal() {
assertEquals(Inefficient.power(2,1),Efficient.power(2,1));
assertEquals(Inefficient.power(2,2),Efficient.power(2,2));
assertEquals(Inefficient.power(2,3),Efficient.power(2,3));
assertEquals(Inefficient.power(2,4),Efficient.power(2,4));
assertEquals(Inefficient.power(3,1),Efficient.power(3,1));
assertEquals(Inefficient.power(3,2),Efficient.power(3,2));
assertEquals(Inefficient.power(3,3),Efficient.power(3,3));
assertEquals(Inefficient.power(3,4),Efficient.power(3,4));
}
}
Testen der Taylor-Reihe für sin
@Test
public void testSinNormal() { assertTrue(
Math.abs(Math.sin(3.1415/2) - Efficient.sin(3.1415/2))
< 1e-6);
}
Beachte: Der Vergleich der Ausgaben mit den Erwartungen muss eventuell akzeptable
Oder verwende:
assertEquals(
double expected,
double actual,
double delta)
Testen von Sortieralgorithmen
4 Sortieralgorithmen BubbleSort
InsertionSort MergeSort SelectionSort
Was sind relativ erschöpfende Testdaten?
Betrachte alle möglichen Listen der Länge 0..n.
Testdaten für das Sortieren
@Before
public void setUp() throws Exception { input0 = new int[0];
output0 = new int[0];
input1 = new int[] { 42 }; // array of length 1 output1 = new int[] { 42 }; // array of length 1
input2a = new int[] { 1, 2 }; // sorted array of length 2 input2b = new int[] { 2, 1 }; // unsorted array of length 2 output2 = new int[] { 1, 2 }; // sorted array of length 2 input3a = new int[] { 1, 2, 3 }; // sorted array of length 3 input3b = new int[] { 2, 3, 1 }; // unsorted array of length 3 input3c = new int[] { 3, 1, 2 }; // unsorted array of length 3 input3d = new int[] { 1, 3, 2 }; // unsorted array of length 3 input3e = new int[] { 3, 2, 1 }; // unsorted array of length 3 input3f = new int[] { 2, 1, 3 }; // unsorted array of length 3 output3 = new int[] { 1, 2, 3 }; // sorted array of length 3 }
Die Testdaten werden neu aufgebaut vor jedem Testfall.
Die Testdaten sind Attribute der
Testfälle zum Sortieren
public void testIsSorted();
public void testIsPermutation();
public void testBubbleSort();
public void testInsertionSort();
public void testMergeSort();
public void testSelectionSort();
public void testBubbleSortWithNull();
public void testInsertionSortWithNull();
public void testMergeSortWithNull();
public void testSelectionSortWithNull();
Eigenschaften zur
Problembeschreibung des Sortierens
Normalfälle und Grenzfälle des Sortierens mit kombinatorische Erschöpfung bis zu gewisser Länge
Fehlerfälle mit “null”
Testen des Sortiertheitstestes
@Test
public void testIsSorted() { // Sorted input
assertTrue(isSorted(input0));
assertTrue(isSorted(input1));
assertTrue(isSorted(input2a));
assertTrue(isSorted(input3a));
// Sorted output
assertTrue(isSorted(output0));
assertTrue(isSorted(output1));
assertTrue(isSorted(output2));
assertTrue(isSorted(output3));
// Unsorted input
assertFalse(isSorted(input2b));
...
Testen des Permutationstestes
@Test
public void testIsPermutation() {
assertTrue(isPermutation(input0,output0));
assertTrue(isPermutation(input1,output1));
assertTrue(isPermutation(input2a,output2));
assertTrue(isPermutation(input2b,output2));
...
}
Testen von BubbleSort
@Test
public void testBubbleSort() { bubbleSort(input0);
assertTrue(Arrays.equals(input0,output0));
bubbleSort(input1);
assertTrue(Arrays.equals(input1,output1));
bubbleSort(input2a);
assertTrue(Arrays.equals(output2,input2a));
bubbleSort(input2b);
assertTrue(Arrays.equals(output2,input2b));
bubbleSort(input3a);
assertTrue(Arrays.equals(output3,input3a));
...
Mutation der
@Before- vorbereiteten
Daten.
Wie testet man Hanoi?
public static void move(int n, String from, String temp, String to) { if (n == 0)
return;
move(n - 1, from, to, temp);
System.out.println("Move disc " + n + " from " + from + " to " + to);
move(n - 1, temp, from, to);
}
Man könnte die Ausgabe unmittelbar in einer Datei sichern und eine Baseline zum Vergleich mit der Ausgabe vereinbaren. Eventuell ziehen wir aber eine
strukturierte Darstellung der Ausgabe vor.
Eine Verbundtyp für Turmbewegungen
public final class Move { public int disc;
public String from;
public String to;
public Move(int disc, String from, String to) { this.disc = disc;
this.from = from;
this.to = to;
} }
Der Konstruktor ist optional.
Er ermöglicht etwas kompakteren Code.
Türme von Hanoi mit dem Füllen eines Feldes von Bewegungen
public static void move(
Move[] r, int n, String from, String temp, String to) { move(r, 0, n, from, temp, to);
}
private static int move(
Move[] r, int p, int n, String from, String temp, String to) { if (n == 0)
return p;
p = move(r, p, n - 1, from, to, temp);
Move m = new Move(n, from, to);
r[p++] = m;
return move(r, p, n - 1, temp, from, to);
}
Fühlstand des Feldes r
Testanwendung
public static void main(String[] args) { Move[] r = new Move[7];
move(r, 3, "A", "B", "C");
System.out.println(Arrays.toString(r));
}
[Move(1,A,C), Move(2,A,B), Move(1,C,B), Move(3,A,C), ...]
Wie können wir solchen
Text erzeugen?
Einschub: toString() per Datentyp
public final class Move { ...
public String toString() {
return "Move(" + disc + "," + from + "," + to + ")";
} }
Diese Methode kann für jeden Klassentyp implementiert
werden. Es gibt keinen
brauchbaren Default.
Testen des Normalfalls für die Türme von Hanoi
public class TestArrayBased {
@Test
public void testNormal() { Move[] expected = {
new Move(1,"A","C"), new Move(2,"A","B"), new Move(1,"C","B"), new Move(3,"A","C"), new Move(1,"B","A"), new Move(2,"B","C"), new Move(1,"A","C") };
Move[] actual = new Move[expected.length];
ArrayBased.move(actual, 3,"A","B","C");
assertArrayEquals(expected, actual);
}
Wann sind zwei
Bewegungen gleich?
Einschub: Strukturelle Gleichheit
public final class Move { ...
public boolean equals(Object o) { if (!(o instanceof Move))
return false;
Move m = (Move)o;
return this.disc == m.disc
&& this.from.equals(m.from)
&& this.to.equals(m.to);
} }
Wir vergleichen Bewegungen komponentenweise.
Dabei fallen Typtest und Down-Cast an, um den Parameter von equals(...) anzupassen.
Diese Methode kann für jeden Klassentyp implementiert werden.
Der Default ist “==”.
Nur
beiläufig
erwähnt.
Der Vertrag von equals
public boolean equals(Object obj)
Indicates whether some other object is "equal to" this one.
The equals method implements an equivalence relation on non-null object references:
• It is reflexive: for any non-null reference value x , x.equals(x) should return true .
• It is symmetric: for any non-null reference values x and y , x.equals(y) should return
true if and only if y.equals(x) returns true .
• It is transitive: for any non-null reference values x , y , and z , if x.equals(y) returns
true and y.equals(z) returns true , then x.equals(z) should return true .
• It is consistent: for any non-null reference values x and y , multiple invocations of
x.equals(y) consistently return true or consistently return false , provided no information used in equals comparisons on the objects is modified.
• For any non-null reference value x , x.equals(null) should return false . The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y , this method returns true if and only if x and y refer to the same object ( x == y has the value
true ).
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html
Nur
beiläufig
erwähnt.
If it´s not tested, it´s broken!
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
getestetem Verhalten Edsger Wybe Dijkstra
*1930 †2002
„Program testing can be used to show the presence of bugs, but
never to show their absence“
Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.