FWP Komponentenorientierte Softwareentwicklung Test-Driven-Development mit Java Hochschule München FK 07 SS 2009 Theis Michael - Senior Developer HVB Information Services GmbH März 2009
Grundlagen des Testens von Software Test-Driven-Development Unit-Testing mit JUNIT und Spring Integrationstests mit Continuous Integration Best practices 2
Motivation für das Testen Was kümmert s mich? Primäres Ziel von Tests ist das Vermeiden von Fehlern Fehler senken Kundenzufriedenheit und loyalität Fehler lassen Projekte scheitern Fehler verursachen Kosten und Umsatzverluste Fehler führen zu Gefahren Was bringt s mir? Testen macht Mut Testen gibt Sicherheit Je eher desto besser Kosten für das Erkennen und Beheben von Fehlern steigen mit dem Projektfortschritt 3
Definition Softwaretest Softwaretests sind analytische und dynamische Qualitätsmaßnahmen zur Sicherstellung der Qualität von Software statisch analytisch Qualitätmaßnahmen dynamisch konstruktiv Nach ANSI/IEEE Std. 610.12-1990: The process of operating a system or component under specified conditions, observing or recording the results and making an evaluation of some aspects of the system or component. Nach Dehnert: Test [ ] der überprüfbare und jederzeit wiederholbare Nachweis der Korrektheit eines Softwarebausteines relativ zu vorher festgelegten Anforderungen 4
Testen stellt die Qualität von Software sicher Aber was ist Softwarequalität? Wartbarkeit Portabilität Usability Effizienz Korrektheit Leistungsfähigkeit Zuverlässigkeit Kompatibilität Vollständigkeit Qualität Sicherheit 5
V-Modell als Modell zur Testklassifizierung Detaillierungsgrad / Systemebene Zeit Anforderungen Spezifikation Entwurf Detaillierter Entwurf P P Unit test Funktionalität Robustheit Effizienz Wartbarkeit N System test Funktionale Anforderungen Nicht funktionale Anforderungen Integration test Schnittstellen Datenaustausch N Acceptance test Vollständigkeit P NP NP Test bei Wartung und Weiterentwicklung der Software Fehlernachtest Test der... geänderten Funktionalität... neuen Funktionalität Vollständiger Regressionstest Testen nicht funktionaler Anforderungen Lasttest Performancetest Volumen-/Massentest Stresstest Test der Datensichheit... Benutzerfreundlichkeit... Robustheit... Stabilität und Zuverlässigkeit... Kompatibilität... Dokumentation... Wartbarkeit... Programmierer testen Implementierung N NP Nicht-Programmierer können testen Programmierer und Nicht-Programmierer testen 6 Kolp Markus, Testbarkeit von EJB-basierten und spring-basierten Komponenten, 2007
Grundlagen des Testens von Software Test-Driven-DevelopmentDevelopment Unit-Testing mit JUNIT und Spring Integrationstests mit Continuous Integration Best practices 7
Test Driven Development TFD Refactoring TDD 8 Scott W.Ambler, Introduction to Test Driven Design, 2003
Ziele und Auswirkungen von TDD Kent Beck definiert als Erfinder des TDDs zwei Ziele Neuer (Business-)Code soll erst dann geschrieben werden, wenn ein automatisierter Test fehlschlägt Doppelte Codesequenzen sollten entfernt werden (DRY principle) Einfache Regeln mit großer Auswirkung Sie designen organisch mit lauffähigem Code als Feedback Sie schreiben die Tests selbst, denn Sie können bei bei einer hohen Testdurchführungsrate nicht auf jemand anderen warten Ihre Entwicklungsumgebung muss in der Lage sein, auf kleine Änderungen eine schnelle Antworten zu liefern Ihr Design muss auf lose gekoppelten Komponenten mit hoher Kohäsion basieren, um das Testen einfacher zu machen 9
Merkmale guter Tests Kurze Durchlaufzeiten Können isoliert ausgeführt werden Benutzen Daten, die sie leicht lesbar und verständlich machen Benutzen echte Daten falls erforderlich Repräsentieren einen Schritt in Richtung des eigentlichen Zieles 10
Grenzen von TDD: Mythen und falsche Vorstellungen Mythos Sie decken mit Tests 100% Ihres Codes ab Sie brauchen nur Unit Tests TDD ist ausreichend fürs Testen TDD skaliert nicht Realität Third-Party Software ist nicht testbar User Interfaces sind schwer zu testen Testskills/-bereitschaft Gilt nur für die einfachsten Anwendungen TDD kann nur die Basis liefern (System-, Integrations- und Abnahmetests weiterhin erforderlich) Teilweise korrekt, lässt sich aber denoch leicht erreichen Unterteilung der Testläufe Schulung 11 Scott W.Ambler, Introduction to Test Driven Design, 2003
Vorgehensweise beim Test Driven Development Test erstellen Tests ausführen OK Fehler Code erstellen Tests ausführen Fehler OK Code refaktorieren OK, Entwicklung wird fortgesetzt Tests ausführen Fehler OK, Entwicklung beendet 12
Testen mit den xunit Tools Code refaktoriert [Tests OK] Grün [Alle Tests OK] Code refaktoriert [Test fehlgeschlagen] Fehler behoben Fehlschlagenden Test hinzugefügt Rot [Test fehlgeschlagen] 13
Grundlagen des Testens von Software Test-Driven-Development Unit-Testing mit JUNIT und Spring Integrationstests mit Continuous Integration Best practices 14
JUNIT als Beispiel Ab JUNIT 4.x werden Testklassen/-methoden über Annotations definiert @Test markiert eine Methode als Testmethode @Before und @After definieren Fixtures für Testmethoden @BeforeClass und @AfterClass definieren Fixtures für Testklassen Bedingungen werden automatisiert über Assertions geprüft Sicherstellen der Testautomatisierung Über sogenannte Runner werden die Tests ausgeführt Ideale Integration in Eclipse 15
Unterstützung von TDD durch Spring Spring unterstützt mit TDD eigenem Spring TestContext Framework Unabhängig vom eingesetzten Testframework (JUNIT, TestNG) Bringt Dependency Injection und Application Contexte in die JUNIT-Welt Entweder auf Annotation-Basis @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"/applicationContext.xml", "/applicationcontext-test.xml"}) public class MyTest { @Autowired // oder @Resource private IService undertest; public void setundertest(iservice service) { this.undertest = service; } Oder mit Basisklassen public class MyTest extends AbstractJUnit4SpringContextTests { private IService undertest; public void setundertest(iservice service) { this.undertest = service; } 16
Grundlagen des Testens von Software Test-Driven-Development Unit-Testing mit JUNIT und Spring Integrationstests mit Continuous Integration Best practices 17
Integrationstest mit Continuous Integration Erstmalig erwähnt von Martin Fowler Basiert auf kontinuierlichem Bauen/Deployen/Testen Schnappschüssen von Sourcecode werden zyklisch automatisiert gebaut, auf einer Integrationsmaschine bereitgestellt und getestet Praktiken für effiziente CI Alle Sourcen in einem Repository (= Versionshaltungssystem) Automatisieren Sie den Build Machen Sie Ihren Build selbst-testend Jeder gibt seine Änderungen täglich frei Vor jeder Freigabe wird auf einer Integrationsmaschine gebaut Halten Sie den Build schnell Testen Sie in einem Klon der Produktionsumgebung Machen Sie es jedem leicht, sich das letzte Buildergebnis zu besorgen Jeder kann sehen was passiert Automatisieren Sie das Deployment 18
Vorteile von Continuous Integration Reduziertes Risiko durch zeitnahe Integration CI verhindert keine Bugs, hilft sie aber zeitnah zu erkennen und zu beheben Fehler können sich nicht erst ansammeln sondern werden sofort behandelt Fehleranzahl nimmt dramatisch ab (insbesondere in Produktion) Automatisiertes Deployment erleichtert häufiges Deployen Neue Features können schnell in Produktion gebracht werden Schnelles Feedback zwischen Kunden und Entwicklung Schnelle Reaktion auf Produktionsprobleme Mögliche Fehlerquellen während des Deployments werden minimiert 19
Grundlagen des Testens von Software Test-Driven-Development Unit-Testing mit JUNIT und Spring Integrationstests mit Continuous Integration Best practices 20
Empfehlungen zum Thema Testen Gewöhnen Sie sich Test Driven Development (TDD) an Beginnen Sie mit einem Testfall Führen Sie den Testfall automatisiert aus Implementieren Sie die zu testende Funktionalität/Komponente Führen Sie den Testfall automatisiert aus Führen Sie solange Refactoring durch, bis der Testfall durchläuft Erstellen Sie JUNIT-Testklassen für alle öffentlich zugänglichen Komponenten (besser: alle Komponenten) Halten Sie Ihre JUNIT-Testklassen immer auf dem neuesten Stand Stellen Sie sicher, dass alle Prüfungen automatisiert durchgeführt werden (assert*) Testen Sie Änderungen an Ihrem Applikations-Code bevor Sie diese Änderung einchecken Eine sinnvolle Testabdeckung und regelmässiges Testen nimmt Ihnen die Angst vor Code-Änderungen und macht Ihnen Mut zum Refactoring! 21
Quellen Kent Beck: Test Driven Development: By Example Addison-Wesley Professional (November 18, 2002) ISBN 978-0321146533 Kent Beck: Extreme Programming Explained: Embrace Change Addison-Wesley Professional; US ed edition (October 5, 1999) ISBN 978-0201616415 Scott W. Ambler: Introduction to Test Driven Design (TDD) http://www.agiledata.org/essays/tdd.html Spring Framework Reference: Testing http://static.springframework.org/spring/docs/2.5.x/reference/testing.h tml JUNIT homepage http://www.junit.org Martin Fowler: Continuous Integration http://www.martinfowler.com/articles/continuousintegration.html 22