Das Test-Framework JUnit ETIS SS04 Gliederung • Motivation • TestFirst • Grundlagen • Assert • TestCase – Lebenszyklus TestCase – UML-Diagramm TestCase • TestSuite • Zusammenfassung JUnit ETIS SS04 2 Motivation (I) • Kostspielige Folgen von Fehlern in Software – SOMIT: Testen wichtig!!! ABER: fast keiner tut es… • Vorurteile: – Keine Zeit, ABER: Tests stabilisieren Code – Keine Lust, ABER: Testen ist kreativ + schafft Vertrauen zum Programm – Mein Code ist fehlerfrei, ABER: Auswirkungen von Verbesserungen auf alten Code? – Testabteilung testet, ABER: Je früher Fehler erkannt, desto besser JUnit ETIS SS04 3 Motivation (II) • Unit - Tests – Test einzelner Komponenten – White-Box-Tests • Anforderungen an Test - Frameworks: – Test- und Anwendungscode getrennt (Größe/Übersicht) – Testfälle unabhängig ausführbar (Fehler finden) – Testergebnis schnell erkennbar • JUnit erfüllt diese Anforderungen JUnit ETIS SS04 4 Motivation(III) • JUnit: Open source Framework – Schreiben und Ausführen automatischer Unit Tests unter Java – Version 3.8.1 (http://www.junit.org/) – In jeder gängigen Java-IDE verwendbar • Autoren: – Kent Beck (Extreme Programming) – Erich Gamma (Mitglied Gang of Four - Design Pattern) • Entsprechende Frameworks für gängige Programmiersprachen erhältlich JUnit ETIS SS04 5 Motivation(IV) – JUnit in eclipse JUnit ETIS SS04 6 TestFirst (I) • Ziel: – Qualitätssicherung: Testbarkeit, Einfachheit • Vorgehen: – Vor eigentlicher Codierung Test schreiben – Erst wenn Test fehlerfrei, dann ist Code fertig – Nur soviel Produktionscode wie Test verlangt – Kleine Schritte (abwechselnd Test- und Produktionscode) – Vor Integration in Gesamtsystem muss Unit Test erfolgreich sein JUnit ETIS SS04 7 TestFirst (II) • Vorteile: – gesamter Code ist getestet (Zerstörung funktionierenden Codes sofort entdeckt) – Tests dokumentieren Code – Schnelles Feedback durch kurze Wechsel Erzeugung von Test- und Produktionscode – Einfaches Design, da durch Test bestimmtes Design • Vorsicht: – Wenn nur triviale Testfälle betrachtet, nutzen Tests wenig... JUnit ETIS SS04 8 Grundlagen • Einbinden der Testklasse in JUnit durch ableiten von Framework-Basisklasse junit.framework.testCase • jede Testklasse erhält Konstruktor für Namen des auszuführenden Testfalls • JUnit erkennt Methode als Testfall, da sie Konvention public void test..() folgt • mit assert-Methoden, z.B. assertTrue(...) kann man Bedingungen testen • bei Fehlerfall bricht JUnit laufenden Testfall mit AssertionFailedError ab JUnit ETIS SS04 9 Assert (I) • Klasse Assert definiert Tests von Werten und Bedingungen, die erfüllt sein müssen, Beispiele: • Test, ob Bedingung wahr – assertTrue(boolean condition) – assertTrue(Fritz.isRadioStation) • Test, ob zwei Objekte gleich (über equals - Methode) – assertEquals(Object expected, Object actual) – assertEquals(“JUnit“, “J“ + “Unit“) JUnit ETIS SS04 10 Assert (II) • Test, ob zwei Fliesskommazahlen gleich sind (bei festzulegender Toleranz) – assertEquals(double expected, double actual, double delta); – assertEquals(3.00, 2.995, 0.005); • Test, ob Objektreferenz null – assertNull(hashMap.get(key)); • Test, ob zwei Referenzen auf selbes Objekt verweisen – assertSame(bar, hashMap.put(“foo“, bar).get(“foo“)); JUnit ETIS SS04 11 TestCase (I) • Ausführung Testfälle auf fixem Satz zu testender Objekte (Test - Fixture) • Pro Testfallmethode meist nur bestimmte Operation der Fixture getestet • Alle Testfälle einer Testklasse sollen von gemeinsamer Fixture Gebrauch machen JUnit ETIS SS04 12 TestCase (II) • Damit fehlerhafte Testfälle andere Testfälle nicht beeinflussen: Test - Fixture neu initialisieren – Testklasse erbt von TestCase – Test-Fixture Instanzvariablen in Testklasse – Methode setUp() überschreiben, um Instanzvariable zu initialisieren – Methode tearDown() überschreiben, um Ressouren (DBVerbindung u.ä.) freizugeben • setUp() wird vor Ausführung eines Testfalls aufgerufen, tearDown() danach JUnit ETIS SS04 13 TestCase (III) public class EuroTest extends TestCase{ private Euro two; public EuroTest(String name){ super (name); } protected void setUp(){ two = new Euro(2.00); } protected void tearDown(){ } } JUnit ETIS SS04 14 Lebenszyklus TestCase 1. Testframework sucht in Testklassen nach öffentlichen Methoden, ohne Parameter und Rückgabewert, die mit test beginnen (Reflection) 2. Sammeln der Methoden in Testsuite + unabhängige Ausführung 3. Für jeden Testfall neue Instanz der Testklasse und damit TestFixture erzeugen, um Seiteneffekte zu vermeiden 4. Vor Ausführung Testfall setUp() aufgerufen (falls neu definiert) 5. test-Methoden ausgeführt 6. Nach Test tearDown (falls neu definiert) 7. Schritte ab 3 wiederholen, bis alle Testfälle einmal ausgeführt JUnit ETIS SS04 15 UML Diagramm TestCase JUnit-Framework Assert assertTrue() assertEquals() assertNull() ... TestCase setUp() tearDown() EigenerTest testMethode() JUnit ETIS SS04 16 TestSuite (I) • Dient dem Zusammenfassen von Tests • Suite: TestSuite - Objekt, dem beliebig viele Tests und Testsuiten hinzugefügt werden können • In statische suite - Methode definiert, welche Tests zusammen auszuführen sind public static Test suite(){ TestSuite suite = new TestSuite(); suite.addTestSuite(CostumerTest.class); suite.addTestSuite(MovieTest.class); return suite; } JUnit ETIS SS04 17 TestSuite(II) – Komposite Pattern <<interface>> 1..n Test tests TestCase JUnit TestSuite ETIS SS04 18 Zusammenfassung • JUnit: Framework für Test von Java - Programmen • Dient Test von Komponenten • Unit Tests sind Investition in die Zukunft • erleichtert es, dem Testcode gleiche Aufmerksamkeit wie Programmcode widmen JUnit ETIS SS04 19 Literatur • http://www.frankwestphal.de/UnitTestingmitJUnit.html • Johannes Link, Unit Tests mit Java, dpunkt.Verlag, 2002 • Barbara Beenen, Einführung in JUnit - Rot - grünes Wechselspiel, javamagazin, 05/04 • Backschat, M., Edlich, J2EE - Entwicklung mit Open Source - Tools, Spektrum Akademischer Verlag, München, 2004 JUnit ETIS SS04 20