Labor "Software Engineering Experiment" Einführung in Test First Sebastian Meyer [email protected] Einführung • „Testen ist das Ausführen eines Programms mit dem Ziel Fehler zu finden“ Myers, The Art of Software Testing • Testen dient nicht dazu die Fehlerfreiheit eines Programms zu beweisen! • Testen ist fester Bestandteil vieler Prozesse – z.B. XP, V-Modell • Automatisch laufende Test ermöglichen Konzentration aufs Wesentliche Sebastian Meyer: Programmierpraktikum 2 Testen mit JUnit • JUnit ist eine Framework für die Entwicklung von Unit-Test in Java – Ein Modul (Unit) ist eine Quellcode-Einheit • Unit-Tests lassen sich automatisiert ausführen – Wiederholbarkeit • JUnit ist in Eclipse integriert • Hier: – JUnit 4 – Java 1.6 Sebastian Meyer: Programmierpraktikum 3 Prinzip des Testens • Es wird ein Soll- mit einem Ist-Wert verglichen • Stimmen beide überein, ist der Test erfolgreich • Stimmen beide nicht überein, ist der Test fehlgeschlagen Sebastian Meyer: Programmierpraktikum 4 Test-Methoden • Testen auf Gleichheit – – – – • Spezialfälle von Gleichheit-Tests – – – – • assertEquals(Object expecteds, Object actuals) assertSame(Object expected, Object actual) assertNotSame(Object expected, Object actual) assertArrayEquals(Object[] expecteds, Object[] actuals) assertTrue(boolean condition) assertFalse(boolean condition) assertNull(Object object) assertNotNull(Object object) Assert-Methoden müssen statisch importiert werden – import static org.junit.Assert.* • Jede Assert-Methode kann beim Fehlschlagen eine Nachricht zeigen – Hierzu gibt es für jede Form eine Erweiterung, die als ersten Parameter einen String übergeben bekommt Sebastian Meyer: Programmierpraktikum 5 Test • Ein Test ist eine öffentliche Methode einer Klasse – public void MethodenName() – Annotiert mit @org.junit.Test (bzw. @Test wenn importiert) • Ein Test bricht ab, wenn eine Assert-Methode fehlschlägt – Gesteuertes Fehlschlagen mittels fail() • Codebeispiel: @Test public void testName() { IAccount account = new Account(); assertEquals("", account.getName()); account.setName(NAME); assertEquals(NAME, account.getName()); } Sebastian Meyer: Programmierpraktikum 6 Testfall • Ein Testfall ist die Zusammenfassung mehrere Tests – In Java eine Klasse mit mehreren Testmethoden • Ein Testfall erlaubt das Initialisieren und Aufräumen vor/nach Tests – @Before, @After wird pro Test ausgeführt – @BeforeClass, @AfterClass wird vor/nach dem Testfall ausgeführt – Daten, die vor jedem Test in einem definierten Zustand sein müssen, werden in @Before deklariert – Daten, deren Zustand für den Test egal ist, werden in @BeforeClass deklariert Sebastian Meyer: Programmierpraktikum 7 TestSuite • Zusammenfassung mehrerer Testfälle – Eine TestSuite ist eine leere Klasse • Annotiert mit – @RunWith(Suite.class) – @Suite.SuiteClasses({Testfall1.class, Testfall2.class,…}) • Codebeispiel: @RunWith(Suite.class) @Suite.SuiteClasses({AccountTest.class, MoneyTransferTest.class}) public class AllTests { } Sebastian Meyer: Programmierpraktikum 8 Vorteil von Interfaces für Unit Tests • Ein Unit Test soll eine Klasse in Isolation testen • Probleme: – – – – Programmeinheiten arbeiten nicht isoliert Aufbau der Testumgebung evtl. aufwändig Testen von Ausnahmesituationen Langsame Test bei Überschreiten der Systemgrenzen • Interfaces helfen diese Probleme zu umgehen – Alle System außerhalb der zu testenden Einheit werden durch Attrappen ersetzt Sebastian Meyer: Programmierpraktikum 9 Was testen? • Jede Methode einer Klasse – Und auch nur die eigenen public void methodeA() { objectB.methodeB() } – MethodeB wird im Test zu ObjectB getestet • Die eigenen Einheiten testen – Nicht fremde Bibliotheken – Nicht die angrenzenden Systeme • Besonders auf Ausnahmen achten – bspw. null-Werte die an eine Funktion übergeben werden Sebastian Meyer: Programmierpraktikum 10 Test – Code – Refactor Zyklus Test hinzufügen Code vereinfachen JUnit: Fehlschlag JUnit: Ok Test erfüllen • grün – rot: Schreiben eines Tests, der fehlschlägt • rot – grün Beheben der Fehler so dass der Test erfolgreich läuft – Nur soviel Code wie nötig schreiben • grün – grün: Duplikation und andere Unschönheiten entfernen Sebastian Meyer: Programmierpraktikum 11 Nicht getesteter Code • Michael Feathers: „Code without tests is bad code. It doesn‘t matter how well written it is […] With tests, we can change the behavior of our code quickly and verifiably. Without them, we really don‘t know if our code is getting better or worse“ • Problem – Um Software sicher zu ändern werden automatische Tests benötigt – Um automatische Tests zu schreiben muss die Software verändert werden Refactoring ohne Tests unumgänglich Sebastian Meyer: Programmierpraktikum 12 Test-First • Test-First (auch: Test Drive Development TDD) kommt aus dem Bereich des eXtreme Programming. • Idee: Zuerst die Test schreiben, dann die Implementierung. • Regeln: – Jeder neue Test soll fehlschlagen – Die Implementierung soll so einfach wie möglich sein Sebastian Meyer: Programmierpraktikum 13 Übung • Schreiben Sie ein Programm, dass Zahlen in die schriftliche deutsche Entsprechung übersetzt – – – – – 1 -> eins 10 -> zehn 100 -> einhundert 125 -> einhundertfünfundzwanzig … Sebastian Meyer: Programmierpraktikum 14