4) validation eines programs mit hilfe von tests · prof. uwe aßmann softwaretechnologie 8...

Post on 18-Sep-2019

3 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Softwaretechnologie, © Prof. Uwe Aßmann 1

4) Validation eines Programs mit Hilfe von Tests

Prof. Dr. rer. nat. Uwe Aßmann

Institut für Software- und Multimediatechnik

Lehrstuhl Softwaretechnologie

Fakultät für Informatik

TU Dresden

Version 11-0.2, 16.04.11

1) Grundlagen

1) Validation und Verifikation

2) Verträge

3) Testfälle

2) Regressionstests mit dem JUnit-Rahmenwerk

3) Entwurfsmuster in JUnit

2Prof. Uwe Aßmann Softwaretechnologie

Literatur

► Obligatorische Literatur■ Zuser Kap. 12 (ohne White-box tests)■ ST für Einsteiger Kap. 12■ www.junit.org ■ Junit 3.x arbeitet noch ohne Metadaten (@Annotationen)

● junit3.8.1/doc/cookstour/cookstour.htm. Schöne Einführung in Junit● junit3.8.1/doc/faq/faq.htm Die FAQ (frequently asked questions)

■ Achtung: JUnit 4 versteckt mehr Funktionalität in Metadaten● http://junit.sourceforge.net/doc/cookbook/cookbook.htm● http://junit.sourceforge.net/doc/faq/faq.htm

► Weiterführend■ Andrew Hunt, David Thomas. The pragmatic programmer. Addison-

Wesley. Deutsch: Der Pragmatische Programmierer. Hanser-Verlag.■ Uwe Vigenschow. Objektorientiertes Testen und Testautomatisierung in

der Praxis. Konzepte, Techniken und Verfahren. dpunkt-Verlag, 2005.

Softwaretechnologie, © Prof. Uwe Aßmann 3

4.1) Grundlagen des Testens

4Prof. Uwe Aßmann Softwaretechnologie

Grundlagen

Validation: Überprüfung der Arbeitsprodukte bzgl. der Erfüllung der Spezifikationen und der Wünsche des Kunden

Verifikation: Nachweis, daß ein Programm seine Spezifikation erfüllt

Formale Verifikation: Mathematischer Beweis desselben

Testen: Überprüfen von Abläufen eines Programms unter bekannten

Bedingungen, mit dem Ziel, Fehler zu finden

Wichtig: Vollständigkeit!

Testing shows the presence of bugs, but never their absence (Dijkstra)

Verifikation zeigt, dass das Programm seine Spezifikation richtig erfüllt.

Validation zeigt, dass das Programm das richtige Problem löst.

Wikipedia:Verification and Validation: In engineering or a quality management system, "verification" is the act of reviewing, inspecting, testing, etc. to establish and document that a product, service, or system meets the regulatory, standard, or specification requirements. By contrast, validation refers to meeting the needs of the intended end-user or customer.

5Prof. Uwe Aßmann Softwaretechnologie

Test-First Development

► Gesetz 62 des Pragmatischen Programmierers: Testen Sie frühzeitig, häufig und automatisch

► Weitere wichtige Gesetze des pragmatischen Programmierers:■ Gesetz 49 (PP): Testen Sie Ihre Software, sonst tun es die Anwender!■ Gesetz 32 (PP): Ein totes Programm richtet weniger Schaden an als ein

schrottreifes.

6Prof. Uwe Aßmann Softwaretechnologie

V-Modell mit Standard-Testprozess (Rechter Ast des V)

► Tests werden bottom-up erledigt:■ Zuerst Verträge und Testfälle für

die Klasse bilden■ Dann die einzelne Klasse testen■ Dann die Komponente■ Dann das System ■ Dann der beta-Test ■ Zum Schluss der

Akzeptanztest (Abnahmetest)

► Bitte, auch so im Praktikum vorgehen.

Analyse

Grobentwurf

Feinentwurf

Implementierung

Abnahmetest

Systemtest

IntegrationstestKomponententest

ZusicherungenMethodentestKlassentest

Testfälle

Testfälle

Testfälle

■ Gesetz 63 (PP): Das Programmieren ist nicht getan, bis alle Tests erfolgreich waren

7Prof. Uwe Aßmann Softwaretechnologie

Software hat eine test-getriebene Architektur

► Ein test-getriebenes System (test-driven system) besteht aus einem Programm (System under Test, SUT) mit seiner Testumgebung (Test-Treiber)

► Tests müssen vor dem Systemeinsatz erfolgreich bestanden werden► Beispiel: TDD (Test-Driven Development)► I.G. zu Programmen hat Software hat eine testgetriebene Architektur

KomparatorKomparator

ProgrammProgramm

Test-Umgebung

Error

OkInput

Eingabedaten

Ausgabedaten(Ist)

Ausgabedaten(Soll)

8Prof. Uwe Aßmann Softwaretechnologie

Beispiel: Wie schreibt man einen Test für eine Methode?

► Wie testet man parseDay(String d)?

// A class for standard representation of dates.public class Date { public int day; public int month; public int year; public Date(String date) { day = parseDay(date); month = parseMonth(date); year = parseYear(date); } public int parseDay(String d) { if (d.matches(„\d\d\.[\s]\d\d\.[\s]\d\d\d\d“)) { // German numeric format day. month. Year return string2Int(d.substring(0,2)); } else { .. other formats... } }}

// A class for standard representation of dates.public class Date { public int day; public int month; public int year; public Date(String date) { day = parseDay(date); month = parseMonth(date); year = parseYear(date); } public int parseDay(String d) { if (d.matches(„\d\d\.[\s]\d\d\.[\s]\d\d\d\d“)) { // German numeric format day. month. Year return string2Int(d.substring(0,2)); } else { .. other formats... } }}

9Prof. Uwe Aßmann Softwaretechnologie

Antwort: Innere Checks und äussere Tests

► Innere Checks (Vertragsprüfungen, contract checks): innerhalb der Methode werden Überprüfungen eingebaut, die bestimmte Zusicherungen erreichen

■ Innere Checks bestehen aus dem Überprüfen von Verträgen innerhalb von Methoden mit Hilfe von Probebeschicken von Methoden mit ausgewählten Parametern (Testdaten)

► Äussere Tests: Nach Aufruf einer Methode mit Testdaten werden Relationen zwischen Ein-, und Ausgabeparametern sowie dem Zustand überprüft

■ Black-box-Tests (schwarze Tests): bestehen aus ● dem Aufstellen von Testfällen (Testdaten für Eingabe-, Ausgabeparametern

und Zustandsbelegungen) ● und deren Überprüfung nach Abarbeitung der Methode ● ohne Kenntnis der Implementierung der Methode

■ White-box-Tests (weiße Tests): dto, ● aber mit Kenntnis über die Implementierung der Methode (z.B. Kenntnis der

Steuerfluss-Pfade)

10Prof. Uwe Aßmann Softwaretechnologie

Innere Checks: Vertragsprüfung für eine Methode

► Invarianten (invariants): Bedingungen über den Zustand (Werte von Objekten und Variablen), die immer gültig sind

► Vorbedingung (precondition, Annahmen, assumptions): ■ Zustand (Werte von Variablen), der vor Aufruf (bzw. Vor Ausführung der

ersten Instruktion) gilt bzw gelten muss■ Typen von Parametern■ Werteeinschränkungen von Parametern

► Nachbedingung (postcondition, Garantien, guarantees, promises):

■ Zustand (Werte von Variablen), die nach Aufruf (bzw. nach Ausführung der letzten Instruktion) gültig sind

■ Zuordnung von Werten von Eingabe- zu Ausgabeparametern (Ein-Ausgaberelation)

Gesetz 31 (PP): Verwenden Sie Design by Contract (Vertragsprüfung), damit der Quelltext nicht mehr und nicht weniger tut, als er vorgibt.

Gesetz 33 (PP): Verhindern Sie das Unmögliche mit Zusicherungen.

11Prof. Uwe Aßmann Softwaretechnologie

Vertragsprüfung für eine Methode mit Exceptions

► Eine fehlgeschlagene Vertragsprüfung kann eine Ausnahme (exception) auslösen, mittels throw-Anweisung

public int parseDay(String d) { if (d.equals(„“) throw DateInvalid; if (d.size() < 10) throw DateTooShort;

if (d.matches(„\d\d\.[\s]\d\d\.[\s]\d\d\d\d“)) { if (d.size() < 10) throw DateTooShort; // German numeric format day. month. Year int day = string2Int(d.substring(0,2)); if (day < 1 or day > 31) throw DayTooLarge; } else { .. other formats... } if (d.size() < 10) throw DateTooShort; if (day < 1 or day > 31) throw somethingWrong; return day;}

public int parseDay(String d) { if (d.equals(„“) throw DateInvalid; if (d.size() < 10) throw DateTooShort;

if (d.matches(„\d\d\.[\s]\d\d\.[\s]\d\d\d\d“)) { if (d.size() < 10) throw DateTooShort; // German numeric format day. month. Year int day = string2Int(d.substring(0,2)); if (day < 1 or day > 31) throw DayTooLarge; } else { .. other formats... } if (d.size() < 10) throw DateTooShort; if (day < 1 or day > 31) throw somethingWrong; return day;}

Vorbedingung (precondition,assumption):

D ist ein StringD ist nicht leer

Invarianten (invariants):D ist mindestens 10 Zeichen

lang (Datum plus Trenner)

Nachbedingung (postcondition,guarantee):

Ein int wird zurückgegebenZwischen 1 und 31

12Prof. Uwe Aßmann Softwaretechnologie

Vertrag einer Methode – Prüfen durch assert

► assert(), eine Standardmethode, bricht das Programm bei Verletzung einer Vertragsbedingung ab

► Achtung: Bedingungen müssen dual zu den Bedingungen der vorgenannten Ausnahmen formuliert sein!

public int parseDay(String d) { assert(!d.equals(„“)); assert(d.size() >= 10));

if (d.matches(„\d\d\.[\s]\d\d\.[\s]\d\d\d\d“)) { assert(d.size() >= 10); // German numeric format day. month. Year int day = string2Int(d.substring(0,2)); assert(day >= 1 and day <= 31); } else { .. other formats... } assert(d.size() >= 10); assert(day >= 1 and day <= 31); return day;}

public int parseDay(String d) { assert(!d.equals(„“)); assert(d.size() >= 10));

if (d.matches(„\d\d\.[\s]\d\d\.[\s]\d\d\d\d“)) { assert(d.size() >= 10); // German numeric format day. month. Year int day = string2Int(d.substring(0,2)); assert(day >= 1 and day <= 31); } else { .. other formats... } assert(d.size() >= 10); assert(day >= 1 and day <= 31); return day;}

13Prof. Uwe Aßmann Softwaretechnologie

Äußere Tests: Aufschreiben von Testfällen in Testfalltabellen

► Ein Testfalltabelle setzt für eine aufzurufende Methode Ein-, Ausgabeparameter, lokale Variablen und Objektattribute in Beziehung.

■ Gut-Fall (Positivtest): Testfall, der bestanden werden muss■ Fehlerfall (Negativtest): Testfall, der scheitern muss■ Ausnahmefall (Exception Test): Testfall, der in einer Exception

(Ausnahme) des Programms enden muss, also einer kontrollierten Fehlersituation

► Die Testfalltabelle spezifiziert also einen Vertrag exemplarisch► Aus jeder Zeile der Testfalltabelle wird ein assert()-Test erzeugt, der

nach dem Aufruf der Prozedur ausgeführt wird■ Testet die Relation der Ein- und Ausgabeparameter, sowie der

Objektattribute

14Prof. Uwe Aßmann Softwaretechnologie

Beispiel: Test einer Datumsklasse

// A class for standard representation of dates.public class Date { public int day; public int month; public int year; public Date(String date) { day = parseDay(date); month = parseMonth(date); year = parseYear(date); } public int equals(Date d) { return day == d.day && year == d.year && month == d.month; }}

// A class for standard representation of dates.public class Date { public int day; public int month; public int year; public Date(String date) { day = parseDay(date); month = parseMonth(date); year = parseYear(date); } public int equals(Date d) { return day == d.day && year == d.year && month == d.month; }}

15Prof. Uwe Aßmann Softwaretechnologie

Beispiel einer zugehörigen Testfalltabelle

► Testfalltabellen enthalten Testfälle (Gut-, Fehler-, Ausnahmefälle)

Nr Klasse Eingabedaten Ausgabedaten Erwarteter Status

day month year

1 Gutfall 1. Januar 2006 1 1 2006 Ok

2 Gutfall 05/12/2008 5 12 2008 Ok

3 Gutfall January 23, 2017 23 1 2017 Ok

4 Fehlerfall 44, 2007 Failure

5 Fehlerfall Aup 23, 2005 Failure

6 Ausnahme March 44, 2007 Exception

16Prof. Uwe Aßmann Softwaretechnologie

FIT Testfalltabellen Framework http://fit.c2.com

► FIT bietet eine Spezifikation der Testfälle in Word oder Excel■ Automatische Generierung von Junit-Testfällen■ Automatischer Feedback

► siehe Softwaretechnologie-II, WS

http://fit.c2.com/files/WelcomeVisitors/example.gif

17Prof. Uwe Aßmann Softwaretechnologie

public class DateTestCase { Date d1; Date d2; Date d3; public int testDate() { d1 = new Date(„1. Januar 2006“); d2 = new Date(„05/12/2008“); d3 = new Date(„January 23rd, 2009“);

assert(d1.day == 1); assert(d1.month == 1); assert(d1.year == 2006); assert(d2.day == 5); assert(d2.month == 12); assert(d2.year == 2008); assert(d3.day == 23); assert(d3.month == 1); assert(d3.year == 2009); }}

public class DateTestCase { Date d1; Date d2; Date d3; public int testDate() { d1 = new Date(„1. Januar 2006“); d2 = new Date(„05/12/2008“); d3 = new Date(„January 23rd, 2009“);

assert(d1.day == 1); assert(d1.month == 1); assert(d1.year == 2006); assert(d2.day == 5); assert(d2.month == 12); assert(d2.year == 2008); assert(d3.day == 23); assert(d3.month == 1); assert(d3.year == 2009); }}

Neuer Testfall

► Testfälle werden in eine Testfallklasse geschrieben■ Die Testdaten befinden sich in einer Halterung (fixture) ■ Eine Testfallklasse kann mehrere Testfälle aus der Testfalltabelle

enthalten

Halterung (fixture)

18Prof. Uwe Aßmann Softwaretechnologie

Wie wähle ich Testdaten aus?

► Bestimme die Extremwerte der Parameter der zu testenden Methode

■ Nullwerte immer testen, z.B. 0 oder null■ Randwerte, z.B. 1.1., 31.12

► Bestimme Bereichseinschränkungen■ Werte ausserhalb eines Zahlenbereichs■ negative Werte, wenn natürliche Zahlen im Spiel sind

► Bestimme Zustände, in denen sich ein Objekt nach einer Anweisung befinden muss

► Bestimme Äquivalenzklassen von Testdaten und teste nur die Repräsentanten

► Bestimme alle Werte aller boolschen Bedingungen in der Methode■ Raum aller Steuerflußbedingungen

Softwaretechnologie, © Prof. Uwe Aßmann 19

4.2) Regressionstests mit dem JUnit-Rahmenwerk

20Prof. Uwe Aßmann Softwaretechnologie

Testfälle

► Testfall: Herbeiführen einer bestimmten Programm-Situation, mit bestimmten Testdaten

► Testdaten: Eingabe, die einen konkreten Testfall herbeiführt ► Testdatensatz: Ein- und Ausgabedaten, die zu einem Testfall

gehören ► Regressionstest: Automatisierter Vergleich von Ausgabedaten

(gleicher Testfälle) unterschiedlicher Versionen des Programms. ■ Da zu großen Systemen mehrere 10000 Testdatensätze gehören, ist ein

automatischer Vergleich unerläßlich.■ Beispiel: Validierungssuiten von Übersetzern werden zusammen mit

Regressionstest-Werkzeugen verkauft. Diese Werkzeuge wenden den Übersetzer systematisch auf alle Testdaten in der Validierungssuite an

21Prof. Uwe Aßmann Softwaretechnologie

Das JUnit Regressionstest-Framework

► JUnit www.junit.org ist ein technisches Java-Framework für Regressionstests, sowohl für einzelne Klassen (unit test), als auch für Systeme

■ Durchführung von Testläufen mit Testsuiten automatisiert■ Eclipse-Plugin erhältlich ■ Mittlerweile für viele Sprachen nachgebaut

► Junit 3.8.1:■ 88 Klassen mit 7227 Zeilen ■ im Kern des Rahmenwerks: 10 Klassen (1101 Zeilen)

► Testresultate:■ Failure (Zusicherung wird zur Laufzeit verletzt)■ Error (Unvorhergesehenes Ereignis, z.B. Absturz)■ Ok

► JUnit-4 versteckt mehr Funktionalität mit Metadaten (@Annotationen) und ist wesentlich komplexer. Empfehlung: Lernen Sie zuerst 3.8.1!

22Prof. Uwe Aßmann Softwaretechnologie

Kern von JUnit 3.8.1

run(TestResult)

Test

run(TestResult)runTest()setUp()tearDown()

TestCase

String name

run(TestResult)add()

TestSuite

component

TestResult

setUp();runTest();tearDown();

MyTestCase

.. init of test datarunTest()setUp()tearDown().. test methodstestConversion()testInput()

TextTestResult

UITestResult

... reason why failed

... test data

*

23Prof. Uwe Aßmann Softwaretechnologie

Exkurs: Erkunde JUnit 3.8.x mit Javadoc

► Aufgabe: ■ laden Sie die API-Dokumentation von JUnit mit einem Brauser Ihrer Wahl■ finden Sie die Aufgabe der Klassen TestResult, TestCase und TestSuite

heraus■ Welche Aufgabe hat die Klasse Assert?

Gesetz 68 (PP): Bauen Sie die Dokumentation ein, anstatt sie dranzuschrauben

/home/ua1/Courses/ST1/Material/junit3.8.1/javadoc/index.html

24Prof. Uwe Aßmann Softwaretechnologie

Beispiel: Test der Datumsklasse in JUnit

// A class for standard representation of dates.public class Date { public int day; public int month; public int year; public Date(String date) { day = parseDay(date); month = parseMonth(date); year = parseYear(date); } public int equals(Date d) { return day == d.day && year == d.year && month == d.month; }}

// A class for standard representation of dates.public class Date { public int day; public int month; public int year; public Date(String date) { day = parseDay(date); month = parseMonth(date); year = parseYear(date); } public int equals(Date d) { return day == d.day && year == d.year && month == d.month; }}

25Prof. Uwe Aßmann Softwaretechnologie

public class DateTestCase extends TestCase { Date d1; Date d2; Date d3; protected int setUp() { d1 = new Date(„1. Januar 2006“); d2 = new Date(„01/01/2006“); d3 = new Date(„January 1st, 2006“); } public int testDate1() { assert(d1.equals(d2)); assert(d2.equals(d3)); assert(d3.equals(d1)); .... more to say here .... } public int testDate2() { .. more to say here .... } protected int tearDown() { .. .. }}

public class DateTestCase extends TestCase { Date d1; Date d2; Date d3; protected int setUp() { d1 = new Date(„1. Januar 2006“); d2 = new Date(„01/01/2006“); d3 = new Date(„January 1st, 2006“); } public int testDate1() { assert(d1.equals(d2)); assert(d2.equals(d3)); assert(d3.equals(d1)); .... more to say here .... } public int testDate2() { .. more to say here .... } protected int tearDown() { .. .. }}

Neuer Testfall in Junit 3.8.x

► TestCases sind Methoden, beginnend mit test

► Initialisierungen der Halterung mit setUp, Abbau mit tearDown

Halterung (fixture)

26Prof. Uwe Aßmann Softwaretechnologie

Testfall als Kunde einer zu testenden Klasse

► Testfallklassen sind also “Kundenklassen” von zu testenden Klassen, ■ die mittels äusserem Test deren Vorbedingungen, Invarianten und

Nachbedingungen überprüfen■ Angewandt auf verschiedene Testdaten

► Testfallklassen imitieren “Kunden”■ unterliegen also dem Lebenszyklus eines objektorientierten Programms ■ Aufbauphase (Testobjektallokation, Vernetzung)■ Arbeitsphase■ Rekonfigurationsphase■ Abbauphase

27Prof. Uwe Aßmann Softwaretechnologie

public class TestApplication { ... TestCase tc = new DateTestCase(„testDate1“); TestResult tr = tc.run();}

public class TestApplication { ... TestCase tc = new DateTestCase(„testDate1“); TestResult tr = tc.run();}

Benutzung von TestCase

► Von Eclipse aus: In einer IDE wie Eclipse werden die Testfall-Prozeduren automatisch inspiziert und gestartet

► Von einem Java-Programm aus: ■ Ein Testfall wird nun erzeugt durch einen Konstruktor der Testfallklasse■ Der Konstruktor sucht die Methode des gegebenen Namens (“testDate1”)

und bereitet sie zum Start vor ● mit Reflektion, d.h. Suche nach dem Methode in dem Klassenprototyp

■ Die run() Methode startet den Testfall gegen die Halterung und gibt ein TestResult zurück

28Prof. Uwe Aßmann Softwaretechnologie

public class TestApplication { ... TestCase tc = new DateTestCase(„testDate1“); TestCase tc2 = new DateTestCase(„testDate2“); TestSuite suite = new TestSuite(); suite.addTest(tc); suite.addTest(tc2); TestResult tr = suite.run(); // Nested test suites TestSuite subsuite = new TestSuite(); ... fill subsuite ... suite.addTest(subsuite); TestResult tr = suite.run();}

Testsuiten

► Eine Testsuite ist eine Kollektion von Testfällen► TestSuites sind komposit

29Prof. Uwe Aßmann Softwaretechnologie

TestRunner GUI

► Die Klassen junit.awtui.TestRunner, junit.swingui.TestRunner bilden einfach GUIs, die Testresultate anzeigen

► Gibt man einem Konstruktor eines Testfalls eine Klasse mit, findet er die “test*”-Methoden (die Testfallmethoden) selbständig

► Dies geschieht mittels Reflektion, d.h. Absuchen der Methodentabellen im Klassenprototypen und Methodenspeicher

public class TestApplication { public static Test doSuite() { // Abbreviation to create all TestCase objects // in a suite TestSuite suite = new TestSuite(DateTestCase.getClass()); } // Starte the GUI with the doSuite suite public static main () { junit.awtui.TestRunner.run(doSuite());}

public class TestApplication { public static Test doSuite() { // Abbreviation to create all TestCase objects // in a suite TestSuite suite = new TestSuite(DateTestCase.getClass()); } // Starte the GUI with the doSuite suite public static main () { junit.awtui.TestRunner.run(doSuite());}

Softwaretechnologie, © Prof. Uwe Aßmann 30

4.2.2) Testläufe in Junit 4.X

31Prof. Uwe Aßmann Softwaretechnologie

Neuer Testfall in Junit 4.X mit Metadaten-Annotationen

► TestCases sind Methoden, annotiert mit @test, Initialisierung und Abräumen mit @before, @after

► Metadaten-Annotationen in Java entsprechen Stereotypen bzw Tagged Values in UML. Sie sind durch Annotationstypen typisiert

public class DateTestCase /* no superclass */ { Date d1; Date d2; Date d3; @before protected int setUp() { d1 = new Date(„1. Januar 2006“); d2 = new Date(„01/01/2006“); d3 = new Date(„January 1st, 2006“); } @test public int compareDate1() { assert(d1.equals(d2)); assert(d2.equals(d3)); assert(d3.equals(d1)); .... more to say here .... } @test public int compareDate2() { .... more to say here .... }}

public class DateTestCase /* no superclass */ { Date d1; Date d2; Date d3; @before protected int setUp() { d1 = new Date(„1. Januar 2006“); d2 = new Date(„01/01/2006“); d3 = new Date(„January 1st, 2006“); } @test public int compareDate1() { assert(d1.equals(d2)); assert(d2.equals(d3)); assert(d3.equals(d1)); .... more to say here .... } @test public int compareDate2() { .... more to say here .... }}

Halterung (fixture)

32Prof. Uwe Aßmann Softwaretechnologie

public class TestApplication { ... DateTestCase tc = new DateTestCase(); Result tr = JUnitCore.run(tc.getClass());}

public class TestApplication { ... DateTestCase tc = new DateTestCase(); Result tr = JUnitCore.run(tc.getClass());}

Benutzung von Testfall-Klasse in 4.x

► Von der Kommandozeile:■ java org.junit.runner.JUnitCore DateTestCase

► Von Eclipse aus: In einer IDE wie Eclipse werden die Testfall-Prozeduren automatisch inspiziert und gestartet

► Von einem Java-Programm aus: ■ Ein Testfall wird erzeugt durch einen Konstruktor der Testfallklasse■ Suche den Klassenprototyp der Testfallklasse■ Die run() Methode von JUnitCore startet alle enthaltenen Testfälle über

den Klassenprotoypen ● Starten aller annotierten Initialisierungen, Testfallmethoden, Abräumer

■ und gibt ein “Result”-Objekt zurück

33Prof. Uwe Aßmann Softwaretechnologie

Junit 4.X mit vielen weiteren Metadaten-Annotationen

► Viele weitere Test-Annotationstypen sind definiert

public class DateTestCase { Date d1; @beforeClass protected int setUpAll() { // done before ALL tests in a class } @afterClass protected int tearDownAll() { // done before ALL tests in a class } @test(timeout=100,expected=IndexOutOfBoundException.class) public int compareDate2() { // test fails if takes longer than 50 msec // test fails if IndexOutOfBoundException is NOT thrown .... more to say here .... }}

public class DateTestCase { Date d1; @beforeClass protected int setUpAll() { // done before ALL tests in a class } @afterClass protected int tearDownAll() { // done before ALL tests in a class } @test(timeout=100,expected=IndexOutOfBoundException.class) public int compareDate2() { // test fails if takes longer than 50 msec // test fails if IndexOutOfBoundException is NOT thrown .... more to say here .... }}

Softwaretechnologie, © Prof. Uwe Aßmann 34

4.3) Entwurfsmuster in JUnit

35Prof. Uwe Aßmann Softwaretechnologie

Was ist ein Entwurfsmuster?

► Ein Entwurfsmuster ist...■ Eine Beschreibung einer Standardlösung für■ Ein Standardentwurfsproblem■ in einem gewissen Kontext

► Ein Entwurfsmuster wiederverwendet bewährte Entwurfsinformation■ Ein Entwurfsmuster darf nicht neu, sondern muss wohlbewährt sein

► Entwurfsmuster sind ein wesentiches Entwurfshilfsmittel aller Ingenieure

■ Maschinenbau■ Elektrotechnik■ Architektur

► Entwurfsmuster treten auch in Frameworks wie JUnit auf

36Prof. Uwe Aßmann Softwaretechnologie

Beispiel: Entwurfsmuster in Junit 3.x

► Entwurfsmuster sind spezifische Szenarien von Klassen

run(TestResult)

Test

run(TestResult)runTest()setUp()tearDown()

TestCase

String name

run(TestResult)add()

TestSuite

Composite

Composite

Leaf

component

TestResult

setUp();runTest();tearDown();

MyTestCase

.. init of test datarunTest()setUp()tearDown()

TextTestResult

UITestResult

... reason why failed

... test data TemplateMethod

*

37Prof. Uwe Aßmann Softwaretechnologie

► Definiert das Skelett eines Algorithmusses in einer Schablonenmethode (template method)

■ Die Schablonenmethode ist konkret

► Delegiere Teile zu abstrakten Hakenmethoden (hook methods)

■ die von Unterklassen konkretisiert werden müssen

► Variiere Verhalten der abstrakten Klasse durch verschiedene Unterklassen

■ Separation des “fixen” vom “variablen” Teil eines Algorithmus

Entwurfsmuster TemplateMethod

...primitiveOperation1();...primitiveOperation2();...

AbstractClass

TemplateMethod()primitiveOperation1()primitiveOperation2()

ConcreteClass

primitiveOperation1()primitiveOperation2()

38Prof. Uwe Aßmann Softwaretechnologie

Beispiel TemplateMethod: Ein Datengenerator

► Parameterisierung eines Generators mit Anzahl und Produktion■ (Vergleiche mit TestCase aus JUnit)

...for (i = 0; i < howOften(); i++) {...produceItem();...

DataGenerator

generate()howOften()produceItem()

TestDataGenerator

howOften()produceItem()

return 5;return 5;

String word = grammar.recurse();println(word);

- Grammar grammar;

39Prof. Uwe Aßmann Softwaretechnologie

Entwurfsmuster Composite

Component

commonOperation()add(Component)remove(Component)getType(int)

Composite

commonOperation()add(Component)remove(Component)getType(int)

Leaf

commonOperation()

ClientchildObjects

for all g in childObjects g.commonOperation()

} Pseudo implementations

*

► Composite besitzt eine rekursive n-Aggregation zur Oberklasse

Aggregation(„has-a“)

40Prof. Uwe Aßmann Softwaretechnologie

Composite in Junit 3.x

► Mehrere Methoden von Test sind komposit strukturiert■ run()■ countTestCases()■ tests()■ toString()

41Prof. Uwe Aßmann Softwaretechnologie

Composite

► Beschreibt Teil/Ganzes-Hierarchien von Laufzeit-Objekten, z.B. geschachtelte Testsuiten und -fälle

:TestSuite

:TestSuite :HisTestCase:MyTestCase

:HisTestCase :MyTestCase:YourTestCase

42Prof. Uwe Aßmann Softwaretechnologie

Bsp.: Zählen von Testfällen in JUnit

abstract class Test {

abstract int countTestCases();

}

class TestSuite extends Test {;

Test [20] children;// here is the n-recursion

int countTestCases() { // common operation

for (i = 0; i <= children.length; i++) {

curNr += children[i].countTestCases();

}

return curNr;

}

void add(Test c) {

children[children.length++] = c;

}

abstract class Test {

abstract int countTestCases();

}

class TestSuite extends Test {;

Test [20] children;// here is the n-recursion

int countTestCases() { // common operation

for (i = 0; i <= children.length; i++) {

curNr += children[i].countTestCases();

}

return curNr;

}

void add(Test c) {

children[children.length++] = c;

}

class TestCase extends Test {

private int myTestCaseCount = 10;

int countTestCases() { // common operation

return myTestCaseCount;

}

void add(Test c) {

/// impossible, dont do anything

}

}

// application

main () { int nr = test.countTestCases(); }

class TestCase extends Test {

private int myTestCaseCount = 10;

int countTestCases() { // common operation

return myTestCaseCount;

}

void add(Test c) {

/// impossible, dont do anything

}

}

// application

main () { int nr = test.countTestCases(); }

Iteratoralgorithmen (map)Faltungsalgorithmen (folding)

43Prof. Uwe Aßmann Softwaretechnologie

Praktikum Wintersemester

► Erstellung eines Akzeptanztestbeschreibung im Vertrag (Pflichtenheft)

■ Ohne Erfüllung kein Bestehen des Praktikums!■ Eine Iteration: Kunde stellt einen Zusatzwunsch: Wie reagiert man auf die

Veränderung?

► Tip: Erstellen Sie sich von Anfang an einen Regressionstest!■ Und lassen sie diesen bei jeder Veränderung laufen, um zu überprüfen,

ob Sie wesentliche Eigenschaften des Systems verändert haben

44Prof. Uwe Aßmann Softwaretechnologie

Was haben wir gelernt?

► Achten Sie auf das Management Ihres Projekts im Praktikum■ Planen Sie hinreichend

► Testen Sie sorgfältig und von Anfang an (test-driven development, TDD)

■ Erstellen Sie eine Akzeptanztestsuite■ Erstellen Sie einen Regressionstest

► Software ohne Tests ist keine Software► Erste Entwurfsmuster TemplateMethod, Composite► Lernen Sie, Java zu programmieren:

■ Ohne ausreichende Java-Kenntnisse weder Bestehen der Klausur noch des Praktikums

■ Nutzen Sie fleissig den Java-Praktomaten!

45Prof. Uwe Aßmann Softwaretechnologie

End

top related