oopm, ralf lämmellaemmel/oopm/slides/testing.pdf · @before ausführung vor jeder testmethode...

50
Testen von Programmen OOPM, Ralf Lämmel http://www.constructionphotography.com In Verfeinerung der Vorlesung zum einfachen Programmtesten

Upload: others

Post on 18-Oct-2020

7 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

Testen von ProgrammenOOPM, Ralf Lämmel

http://www.constructionphotography.com

In Verfeinerung der

Vorlesung zum einfachen

Programmtesten

Page 2: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Testen mit JUnit

330

Page 3: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Ein naiver Testfall

331

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}

}

Wie wird dies kontrolliert?

Sind damit alle Fälle getestet?

Page 4: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 332

import org.junit.Test;import static org.junit.Assert.*;

public class TestPrimitiveRecursive {@Testpublic 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

Page 5: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Ausführen von JUnit-Tests

333

“Grün” bedeutet, dass alle Tests

erfolgreich waren.

Page 6: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Systematisches Testen mit dem JUnit-Framework

334

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.

Page 7: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

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

335

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

Page 8: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

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)

336

Reihenfolgebeachten!

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

Page 9: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Hinweise zur Verständlichkeit

Sprechende Testnamen (Vergl. testAddUserWithoutPasswd() vs. test1().)

Einfacher und kurzer Code für Testmethoden (Komplexe Tests testen oft mehrere Dinge auf einmal.)

Nähe zwischen Eingaben und erwartetem Ergebnis (Damit sind Tests besser nachvollziehbar.)

337

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

Page 10: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Test-Driven Development (TDD)

338

Eine Idee des „Extreme Programming“

Tests sind genau so wichtig wie Funktionalität.

Testfälle zuerst, danach die Implementation.

„Constantly testing“

„Daily Build“

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

Page 11: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Mehr JUnit-Beispiele

339

Normalfälle Grenzfälle Fehlerfälle

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

Page 12: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Fehlerfall zur Addition

340

@Test(expected=java.lang.StackOverflowError.class)

public void testAdd1stNegative() {

PrimitiveRecursive.add(-1,0);

}

Dokumentation der erwarteten Ausnahme für den Fehlerfall

Page 13: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Fehlerfall zum MergeSort

341

@Test(expected=java.lang.NullPointerException.class)

public void testMergeSortWithNull() {

mergeSort(null);

}

Dokumentation der erwarteten Ausnahme für den Fehlerfall

Page 14: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Alternative:Grenzfall zum MergeSort

342

public void testMergeSortWithNull() {

int[] x = null;

mergeSort(x);

assertNull(x);

}

Page 15: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Fehlerfälle zum ggT

343

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

Page 16: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Grenzfälle

344

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.

Page 17: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Grenzfälle für lineare Suche

345

public class TestLinear {public static int[] a = {1,2,3,4,5,6,7,9,10};@Testpublic void testFirst() {

assertEquals(0,Program.linear(a, 1));}@Testpublic void testLast() {

assertEquals(8,Program.linear(a, 10));}

...}

Das sind 9 Werte auf den Indizes 0--8.

Page 18: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Normalfälle für lineare Suche

346

public class TestLinear {public static int[] a = {1,2,3,4,5,6,7,9,10};@Testpublic void testSecond() {

assertEquals(1,Program.linear(a, 2));}@Testpublic void testMissing() {

assertEquals(-1,Program.linear(a, 8));}

...}

Page 19: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Fakultätsfunktion

347

/** * @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;

}

Page 20: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Normalfälle für Fakultätsfunktion

348

@Testpublic void testFactorialOf1to4() {

assertEquals(1, factorial(1));assertEquals(2, factorial(2));assertEquals(6, factorial(3));assertEquals(24, factorial(4));

}

Page 21: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Grenzfall oder Normalfall?

349

@Test

public void testFactorialOf0() {

assertEquals(1, factorial(0));

}

Aus programmiertechnischer Sicht könnte dies als Grenzfall gelten.

Page 22: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Fehlerfall zur Fakultätsfunktion

350

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

Page 23: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Grenzfall zur Fakultätsfunktion

351

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

Page 24: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Spezifikationen beim Blackbox-Testen

352

Page 25: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Methode zur Addition mit “Spezifikation”

353

/** * @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.

Page 26: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Anforderungen an Spezifikation

354

Natürlichsprachlich, semiformal oder formal

Eindeutig

Präzise

Korrekt

Vollständig

Widerspruchsfrei

In der Praxis sind diese Anforderungen möglicherweise zu “teuer”. Allerdings helfen Tests als

indirekte Spezifikation.

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

Page 27: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Methode zur Addition mit geänderter “Spezifikation”

355

/** * @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.

Page 28: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Bestandteile einer Methodenspezifikation

356

Vorbedingung

Nachbedingung

Eingabeparameter

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.

Page 29: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Mehr Beispiele für das Testen

FakultätReferenzimplementation als Orakel

PotenzierungReferenzimplementation als Orakel

Reihentwicklung für SinusGenauigkeitsschranken für Vergleich

SortieralgorithmenErschöpfende Fallunterscheidung

Türme von HanoiHerausforderung an die Testbarkeit

357

Page 30: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Fakultät

358

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

}

@Testpublic void testFactorialOf0to10() {

for (int i = 0; i <= 10; i++)assertEquals( PrimitiveRecursive.factorial(i),

TailRecursive.factorial(i));}

Referenzimplementation

Optimierte Implementation

Test

Page 31: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Testen der Potenzierung

359

Page 32: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Potenzierung(Ineffiziente Referenzimplementation)

360

public static int power(int x, int n) {int result = 1;for (int i=1; i<=n; i++)

result *= x;return result;

}

Page 33: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Potenzierung(Effizientere Implementation)

361

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;

}

Page 34: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Testen mittels Referenzimplementation

362

public class TestEfficient {@Testpublic 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));

}}

Page 35: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Testen der Taylor-Reihe für sin

363

@Testpublic 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

Abweichungen einplanen.

Oder verwende:

assertEquals( double expected, double actual, double delta)

Page 36: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

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.

364

Page 37: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Testdaten für das Sortieren

365

@Beforepublic void setUp() throws Exception {

input0 = new int[0];output0 = new int[0];input1 = new int[] { 42 }; // array of length 1output1 = new int[] { 42 }; // array of length 1input2a = new int[] { 1, 2 }; // sorted array of length 2input2b = new int[] { 2, 1 }; // unsorted array of length 2output2 = new int[] { 1, 2 }; // sorted array of length 2input3a = new int[] { 1, 2, 3 }; // sorted array of length 3input3b = new int[] { 2, 3, 1 }; // unsorted array of length 3input3c = new int[] { 3, 1, 2 }; // unsorted array of length 3input3d = new int[] { 1, 3, 2 }; // unsorted array of length 3input3e = new int[] { 3, 2, 1 }; // unsorted array of length 3input3f = new int[] { 2, 1, 3 }; // unsorted array of length 3output3 = new int[] { 1, 2, 3 }; // sorted array of length 3

}

Die Testdaten werden neu aufgebaut vor jedem Testfall.

Die Testdaten sind Attribute der Testklasse damit alle Testmethoden

darauf zugreifen können.

Page 38: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Testfälle zum Sortieren

366

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”

Page 39: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Testen des Sortiertheitstestes

367

@Testpublic void testIsSorted() {

// Sorted inputassertTrue(isSorted(input0));assertTrue(isSorted(input1));assertTrue(isSorted(input2a));assertTrue(isSorted(input3a));

// Sorted outputassertTrue(isSorted(output0));assertTrue(isSorted(output1));assertTrue(isSorted(output2));assertTrue(isSorted(output3));

// Unsorted inputassertFalse(isSorted(input2b));...

}

Page 40: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Testen des Permutationstestes

368

@Test

public void testIsPermutation() {

assertTrue(isPermutation(input0,output0));

assertTrue(isPermutation(input1,output1));

assertTrue(isPermutation(input2a,output2));

assertTrue(isPermutation(input2b,output2));

...

}

Page 41: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Testen von BubbleSort

369

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

Page 42: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Wie testet man Hanoi?

370

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.

Page 43: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 371

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.

Warum?

Page 44: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Türme von Hanoi mit dem Füllen eines Feldes von Bewegungen

372

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

Page 45: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Testanwendung

373

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?

Page 46: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Einschub: toString() per Datentyp

374

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.

Page 47: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau 375

Testen des Normalfalls für die Türme von Hanoi

public class TestArrayBased {@Testpublic 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?

Page 48: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Einschub: Strukturelle Gleichheit

376

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.

Page 49: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Der Vertrag von equals

377

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

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html

Nur beiläufig erwähnt.

Page 50: OOPM, Ralf Lämmellaemmel/oopm/slides/testing.pdf · @Before Ausführung vor jeder Testmethode (z.B. zum Erstellen von Testdaten) @After Ausführung nach jeder Testmethode... Ausführung

(C) Ralf Lämmel, OOPM, Universität Koblenz-Landau

Zusammenfassung Methodenspezifikationen

Vorbedingungen für Argumente (und Zustand)Nachbedingungen für Resultat (und Zustand)

Testfälle für Normal-, Grenz- und FehlerfälleSystematische Verwendung von Unit-Testen (JUnit)

Ausblick Statische Verifikation von Spezifikationen