• Keine Ergebnisse gefunden

Testen von Programmen

N/A
N/A
Protected

Academic year: 2021

Aktie "Testen von Programmen"

Copied!
73
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Testen von Programmen

OOPM, Ralf Lämmel

(2)

Naives Testen versus

systematischeres Testen

Ausgewählter Beispielcode für die Vorlesung:

http://svn.code.sf.net/p/developers/code/repository/oopm/eclipse/simpletest/

(3)

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 ...

}

}

(4)

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 ...

}

}

(5)

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?

(6)

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

(7)

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.

(8)

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.

(9)

Methoden zum

systematischen Testen

(10)

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.

(11)

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.

(12)

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.

(13)

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.

(14)

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.

(15)

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

(16)

Definition:

Alle Funktionen werden aufgerufen.

Beispiel:

Jeglicher Aufruf von foo.

Glassbox-Testen

Funktionsüberdeckung

(17)

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

(18)

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

(19)

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?

(20)

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

(21)

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.

(22)

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.

(23)

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

(24)

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

(25)

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.

(26)

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.

(27)

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.

(28)

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.

(29)

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.

(30)

Testen mit JUnit

(31)

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

(32)

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

(33)

Ausführen von JUnit-Tests

“Grün” bedeutet,

dass alle Tests

(34)

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.

(35)

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.

(36)

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.

(37)

Mehr JUnit-Beispiele

Danksagung: Teile dieser Vorlesung gehen auf Dr. Volker Riediger’s OOPM 2008 Vorlesung zum Testen zurück.

(38)

Fehlerfall zur Addition

@Test(expected=java.lang.StackOverflowError.class) public void testAdd1stNegative() {

PrimitiveRecursive.add(-1,0);

}

Dokumentation der erwarteten

Ausnahme für den Fehlerfall

(39)

Fehlerfall zum MergeSort

@Test(expected=java.lang.NullPointerException.class) public void testMergeSortWithNull() {

mergeSort(null);

}

Dokumentation der erwarteten

Ausnahme für den Fehlerfall

(40)

Alternative:

Grenzfall zum MergeSort

public void testMergeSortWithNull() { int[] x = null;

mergeSort(x);

assertNull(x);

}

(41)

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);

}

(42)

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.

(43)

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.

(44)

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));

} ...

}

(45)

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;

}

(46)

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));

}

(47)

Grenzfall oder Normalfall?

@Test

public void testFactorialOf0() { assertEquals(1, factorial(0));

}

Aus programmiertechnischer Sicht

könnte dies als Grenzfall gelten.

(48)

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.

(49)

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.

(50)

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

(51)

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

(52)

Testen der Potenzierung

(53)

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;

}

(54)

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;

(55)

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));

}

}

(56)

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)

(57)

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.

(58)

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

(59)

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”

(60)

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));

...

(61)

Testen des Permutationstestes

@Test

public void testIsPermutation() {

assertTrue(isPermutation(input0,output0));

assertTrue(isPermutation(input1,output1));

assertTrue(isPermutation(input2a,output2));

assertTrue(isPermutation(input2b,output2));

...

}

(62)

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.

(63)

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.

(64)

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.

(65)

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

(66)

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?

(67)

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.

(68)

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?

(69)

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.

(70)

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.

(71)

If it´s not tested, it´s broken!

(72)

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.

(73)

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.

Referenzen

ÄHNLICHE DOKUMENTE

Ergänzen Sie die Reaktionsgleichungen so, dass bei allen Elementen die Massenerhaltung gilt..

Bestimmen Sie mit Hilfe des Periodensystems die Ladung der Ionen in den folgenden Verbindungen.. Geben Sie die Ionen mit ihrer Ladung an, zum Beispiel:

Wenn sie den Objektnamen schreiben und einen Punkt eingeben erscheinen alle

Die Verantwortung für den Inhalt dieser Veröffentlichung liegt beim Autor/bei der Autorin... Wir

I Dynamische Tests führen das Programm unter kontrollierten Bedingungen aus, und prüfen das Ergebnis gegen eine gegebene Spezifikation. I Zentrale Frage: wo kommen die

I strukturelle Fehler, die zu einem fehlerhaften Verhalten führen (Programmabbruch, Ausnahmen, etc).

➢ Verwerfen der Hypothese, falls Daten außerhalb der Konfidenzregion. Oft statt vorheriger Wahl von  → Angabe

Programmtext, der vor und nach jedem Test ausgef¨ uhrt werden soll, kann in Methoden mit den Annotationen @Before und. @After