Software Engineering Test Automatiserung und Junit, Test Driven ( test first) Development Prof. Adrian A. Müller, PMP, PSM 1, CSM Fachbereich Informatik und Mikrosystemtechnik Prof. A. Müller, HS KL Software Engineering 2015 1
Testautomatisierung Manuelle Test sind aufwändig und fehleranfällig Insbesondere Regressionstests (Testwiederholungen nach Änderungen) lassen sich manuell nicht in größerem Umfang durchführen Einsatz von Testframeworks Hier verwendet: JUnit Zum Testen von Java-Programmen. Die Tests werden selbst ebenfalls in Java geschrieben. JUnit ist Open Source. In Eclipse ist es bereits integriert. Vergleichbare Tools gibt es auch für andere Sprachen Prof. A. Müller, HS KL Software Engineering 2015 2
JUnit-Test Beispiel Die zentralen Junit-Klassen liegen im Paket org.junit import org.junit.assert; import org.junit.test; Konvention zur Benennung von Testklassen: Name der getesteten Klasse + Test Konvention zur Benennung von Testfällen: Der Name beginnt mit test, enthält häufig Namen der zu testenden Methode Alle mit annotierten Methoden werden von Junit als Testfälle interpretiert und beim Testen ausgeführt Assertion (Zusicherung) public class Mitarbeiter1Test { public void testkonstruktor(){ Mitarbeiter m = new Mitarbeiter("Ute","Mai"); Assert.assertTrue("korrekter Vorname", m.getvorname().equals("ute")); Assert.assertTrue("korrekter Nachname", m.getnachname().equals("mai")); public void testeindeutigeid(){ Assert.assertTrue("unterschiedliche ID", new Mitarbeiter("Ute","Mai").getId()!= new Mitarbeiter("Ute","Mai").getId()); Boolescher Wert, der überprüft wird Dieser String wird ausgegeben, wenn die Zusicherung nicht erfüllt ist. Ein Test kann mehrere Assertions enthalten. Sobald allerdings eine negativ ausfällt, werden die weiteren nicht mehr ausgeführt. Daher ist es häufig sinnvoll, nur eine Assertion pro Test zu verwenden. Quelle: Stephan Kleuker, Qualitätssicherung durch Prof. Softwaretests. A. Müller, HS KL Springer Vieweg 2013. Software Engineering 2015 3
Nutzung mit statischem Import Statischer Import der Klassenmethoden von Assert import static org.junit.assert.*; import org.junit.test; public class Mitarbeiter1Test { public void testkonstruktor(){ Mitarbeiter m = new Mitarbeiter("Ute","Mai"); asserttrue("korrekter Vorname", m.getvorname().equals("ute")); asserttrue("korrekter Nachname", m.getnachname().equals("mai")); Dann kann man die assert-methoden ohne Angabe der Klasse Assert aufrufen public void testeindeutigeid(){ asserttrue("unterschiedliche ID", new Mitarbeiter("Ute","Mai").getId()!= new Mitarbeiter("Ute","Mai").getId()); Prof. A. Müller, HS KL Software Engineering 2015 4
Junit Testausführung in Eclipse Alle Tests erfolgreich ausgeführt Prof. A. Müller, HS KL Software Engineering 2015 5
Junit Negatives Ergebnis 1 Test ist fehlgeschlagen. Erfolgreicher Test Fehlgeschlagener Test Ausgabe des bei der Zusicherung angegebenen Strings Zeilenangabe der fehlgeschlagenen Zusicherung Prof. A. Müller, HS KL Software Engineering 2015 6
Fehler im Test Ein fehlgeschlagener Test muss nicht durch einen Fehler im Programm verursacht sein auch der Test kann fehlerhaft sein Prof. A. Müller, HS KL Software Engineering 2015 7
Assert-Methoden (Auswahl) assertarrayequals(object[] expecteds, Object[] actuals) Asserts that two object arrays are equal. assertequals(object expected, Object actual) Asserts that two objects are equal assertequals(double expected, double actual, double delta) Asserts that two doubles or floats are equal to within a positive delta. assertfalse(boolean condition) Asserts that a condition is false. assertnotnull(object object) Asserts that an object isn't null. assertnull(object object) Asserts that an object is null. assertsame(object expected, Object actual) Asserts that two objects refer to the same object. asserttrue(boolean condition) Asserts that a condition is true. fail() Fails a test with no message. Alle Methoden gibt es auch noch mit einem String- Parameter für eine Ausgabe beim Scheitern des Tests. Hat gegenüber asserttrue den Vorteil, dass bei einem Fehlschlag der erwartete und der tatsächliche Wert ausgegeben werden. Maximale Differerenz, bis zu der die double-werte als gleich gelten sollen. Sorgt dafür, dass der Test garantiert scheitert (um Zeilen zu markieren, die nicht erreicht werden sollen, z. B. wenn vorher eine Exception erwartet wird. Quelle: http://kentbeck.github.com/junit/javadoc/latest/ Prof. A. Müller, HS KL Software Engineering 2015 8
Test-Fixtures Test-Fixture (Fixture = Einrichtung, Ausstattung ) Gemeinsame Grundlage für alle Tests, z. B. Anlegen von Objekten, Initialisieren von Daten import org.junit.assert; import org.junit.before; import org.junit.test; public class Mitarbeiter2Test { Mitarbeiter m1; Wird vor jedem der beiden Tests ausgeführt @Before public void setup() throws Exception { m1 = new Mitarbeiter("Uwe","Mey"); m1.addfachgebiet(fachgebiet.analyse); m1.addfachgebiet(fachgebiet.c); m1.addfachgebiet(fachgebiet.java); public void testhatfaehigkeit1(){ Assert.assertTrue("vorhandene Faehigkeit",m1.hatFachgebiet(Fachgebiet.C)); public void testhatfaehigkeit2(){ Assert.assertTrue("nicht vorhandene Faehigkeit",!m1.hatFachgebiet(Fachgebiet.TEST)); Quelle: Stephan Kleuker, Qualitätssicherung durch Prof. Softwaretests. A. Müller, HS KL Springer Vieweg 2013. Software Engineering 2015 9
Test Fixtures Annotationen @Before @After Wird vor jedem einzelnen Test ausgeführt, z. B. Anlegen von Objekten oder Datensätzen in einer Datebank. Wird nach jedem einzelnen Test ausgeführt, z. B. Änderungen der Testdaten in der Datenbank rückgängig machen, damit sie für den nächsten Test wieder unverändert zur Verfügung stehen. @BeforeClass Statische Methode, wird einmalig ganz am Anfang durchgeführt (nicht vor jedem Test wiederholt). Objekte und Daten, die für alle Tests zur Verfügung stehen sollen können in statischen Attributen gespeichert werden. Die Werte gewöhnlicher Instanzattribute der Testklasse stehen nur innerhalb des jeweiligen Tests zur Verfügung, da bei jedem Test ein neues Objekt angelegt wird. @AfterClass Statische Methode, wird einmalig ganz am Ende durchgeführt, um z. B. Änderungen rückgängig zu machen. Prof. A. Müller, HS KL Software Engineering 2015 10
Exceptions in Tests Tritt eine unerwartete Exception auf, so wird diese als Error gemeldet (im Gegensatz zu einem Failure, der ein nicht erwartetes Ergebnis anzeigt). public void testkonstruktor(){ new Mitarbeiter(null,null); (expected=illegalargumentexception.class) public void testaddfaehigkeit1(){ m1.addfachgebiet(fachgebiet.test); (expected=illegalargumentexception.class) public void testaddfaehigkeit2(){ m1.addfachgebiet(fachgebiet.c); public void testaddfaehigkeit3(){ try{ m1.addfachgebiet(fachgebiet.test); Assert.fail("fehlende Exception"); catch(illegalargumentexception e){ Assert.assertNotNull(e.getMessage()); catch(exception e){ Assert.fail("unerwartet "+e); Quelle: Stephan Kleuker, Qualitätssicherung durch Prof. Softwaretests. A. Müller, HS KL Springer Vieweg 2013. Software Engineering 2015 public void testaddfaehigkeit4(){ try{ 11
Explizit Testen, ob Exceptions richtig geworfen werden (a) Angabe, welche Exception bei diesem Test erwartet wird. public void testkonstruktor(){ new Mitarbeiter(null,null); Hier trat die erwartete Exception auf (expected=illegalargumentexception.class) public void testaddfaehigkeit1(){ m1.addfachgebiet(fachgebiet.test); (expected=illegalargumentexception.class) public void testaddfaehigkeit2(){ m1.addfachgebiet(fachgebiet.c); public void testaddfaehigkeit3(){ try{ m1.addfachgebiet(fachgebiet.test); Assert.fail("fehlende Exception"); catch(illegalargumentexception e){ Assert.assertNotNull(e.getMessage()); catch(exception e){ Assert.fail("unerwartet "+e); Quelle: Stephan Kleuker, Qualitätssicherung durch Prof. Softwaretests. A. Müller, HS KL Springer Vieweg 2013. Software Engineering 2015 public void testaddfaehigkeit4(){ Hier trat die erwartete Exception nicht auf, d. h. der Test ist fehlgeschlagen. 12
Explizit Testen, ob Exceptions richtig geworfen werden (b) public void testkonstruktor(){ new Mitarbeiter(null,null); (expected=illegalargumentexception.class) public void testaddfaehigkeit1(){ m1.addfachgebiet(fachgebiet.test); (expected=illegalargumentexception.class) public void testaddfaehigkeit2(){ m1.addfachgebiet(fachgebiet.c); public void testaddfaehigkeit3(){ try{ m1.addfachgebiet(fachgebiet.test); Assert.fail("fehlende Exception"); catch(illegalargumentexception e){ Assert.assertNotNull(e.getMessage()); catch(exception e){ Assert.fail("unerwartet "+e); public void testaddfaehigkeit4(){ try{ m1.addfachgebiet(fachgebiet.c); catch(exception e){ Assert.fail("unerwartet "+e); Hier wird eine IllegalArgumentException erwartet. Tritt keine oder eine andere Exception auf, wird dies als Failure behandelt.. Hier wird keine Exception erwartet. Ein Auftreten wird daher als Failure behandelt. Quelle: Stephan Kleuker, Qualitätssicherung durch Prof. Softwaretests. A. Müller, HS KL Springer Vieweg 2013. Software Engineering 2015 13
Testautomatisierung Mit Hilfe von JUnit lassen sich vor allem Unit-Tests gut unterstützen Durch Einsatz von Fixtures können auch Integrationsund Systemtests automatisiert werden Schwieriger: Automatisiertes Testen der Oberfläche Auch hierfür gibt es Tools (eg. Capture-and-Replay ) Oberflächentests sind aufwändiger, da z. B. die verschiedenen Eingabelemente eindeutig identifiziert und im Rahmen eines Tests in der richtigen Reihenfolge mit Eingaben versehen und betätigt werden müssen Prof. A. Müller, HS KL Software Engineering 2015 14
Aufgabe Gegeben ist die folgende Klasse: public class Rechner { public int berechnerestguthaben(int guthaben, int ausgabe) { int restguthaben = guthaben - ausgabe; if(guthaben < 0 restguthaben < 0){ throw new NegativesGuthabenException("Negatives Guthaben unzulässig"); return restguthaben; Schreiben Sie eine Klasse mit Junit-Tests Zu Beginn soll ein von allen Tests genutztes Rechner-Objekt angelegt und in einem statischen Attribut gespeichert werden Schreiben Sie einen Test, der das normale Verhalten der Methode prüft Schreiben Sie einen Test, der das Werfen der Exception überprüft Prof. A. Müller, HS KL Software Engineering 2015 15
package testen; import static org.junit.assert.*; import org.junit.test; import org.junit.beforeclass; public class RechnerTest { private static Rechner r; @BeforeClass public static void legerechneran(){ r = new Rechner(); public void test1() { assertequals(20, r.berechnerestguthaben(100, 80)); (expected=negativesguthabenexception.class) public void test5() { assertequals(100, r.berechnerestguthaben(-10, 0)); Prof. A. Müller, HS KL Software Engineering 2015 16
Test-Driven Development Prof. A. Müller, HS KL Software Engineering 2015 17
Mischung von Testen, Vorgehensmodell und SW-Design: TDD Quelle: en.wikipedia.org Test-driven development 1. Add a test 2. Run all tests and see if the new one fails 3. Write some code 4. Run the automated tests and see them succeed 5. Refactor code Voraussetzungen Vor- und Nachteile Prof. A. Müller, HS KL Software Engineering 2015 18
Test Driven Development Quelle: Objektorientiertes Testen und Testautomatisierung in der Praxis, Vigenschow, 2004 Prof. A. Müller, HS KL Software Engineering 2015 19
Test Driven Development Quelle: Objektorientiertes Testen und Testautomatisierung in der Praxis, Vigenschow, 2004 Prof. A. Müller, HS KL Software Engineering 2015 20
Test Driven Development Quelle: Objektorientiertes Testen und Testautomatisierung in der Praxis, Vigenschow, 2004 Prof. A. Müller, HS KL Software Engineering 2015 21
Test Driven Development Quelle: Objektorientiertes Testen und Testautomatisierung in der Praxis, Vigenschow, 2004 Prof. A. Müller, HS KL Software Engineering 2015 22
Anhang Prof. A. Müller, HS KL Software Engineering 2015 23
Testautomatisierung Quelle: http://de.wikipedia.org/wiki/testroboter Am Markt stehen eine Reihe von Testrobotern zur Verfügung. Ihr Umfang bezüglich ihrer Funktionalität variiert jedoch sehr stark. Einige Werkzeuge sind reine Testroboter. Bei anderen wiederum ist die Roboterfunktion nur ein Teil ihrer Gesamtfunktionalität. Selenium: Selenium ist ein Open Source Testframework zur Durchführung funktionsorientierter Tests von Webapplikationen. CitraTest: CitraTest ist eine Lösung der Firma Tevron. CitraTest ist ein Testroboter, der für Funktions- und Lasttests als auch zum End-to-End Monitoring (auch unter Terminalservices wie z.b. Citrix) eingesetzt werden kann. JStudio SiteWalker: JStudio SiteWalker ist ein Testwerkzeug für webbasierte Anwendungen zur Durchführung von automatisierten funktionsorientierten Tests. IBM Rational Robot: Rational Robot von IBM ist ein Testroboter zur Durchführung von Funktions-, Rückfall- und Konfigurationstests für.net-, Java-, Web- und andere GUI-basierte Anwendungen. Ranorex: Ranorex ist ein GUI Testautomatisierungsframework zur Generierung automatisierter Tests für Desktop-, Web-Applikationen und mobile Anwendungen. Es wird vom gleichnamigen Unternehmen entwickelt und vertrieben. TestPartner: TestPartner wurde ursprünglich von der Firma Compuware entwickelt und wird zurzeit von der Firma Micro Focus vertrieben. Bei TestPartner werden zwei verschiedene Modi zur Erstellung von Testfällen angeboten. Mit Visual Test wird ein Storyboard-basierter Ansatz verwendet und mit Test Script werden die Testfälle mit Hilfe eines VBA Codes generiert. HP QuickTest Professional: HP QuickTest Professional ist der aktuelle Testroboter von der Firma HP. Er ersetzt den Testroboter der bislang unter WinRunner vertrieben wurde. Der vollständige Support von WinRunner wird am 1. August 2009 eingestellt. Ein eingeschränkter Support ist bis zum 1. Januar 2011 limitiert. Von der Firma HP wird eine Migration der Testfälle von WinRunner auf HP QuickTest Professional angeboten. Borland SilkTest: Die Firma Borland bietet mit SilkTest eine umfangreiche Lösung zum Testen der Softwarefunktionalitäten von Anwendungen, die über eine grafische Benutzeroberfläche gesteuert werden, an. QF-Test: Mit dem Tool QF-Test der Firma Quality First Software lassen sich u. a. via Capture / Replay Aufzeichnungen zur Automatisierung von Java und Web GUI Funktions-, Regressions- und Lasttests durchführen. Watij: Bei Watij (Web Application Testing in Java) handelt es sich um ein Open-Source-Framework in Java. Es besitzt weder eine grafische Bedienoberfläche noch wird Capture & Replay unterstützt. Die Tests müssen manuell codiert und danach compiliert werden. Yawet: Yawet ist ein Testroboter von der Firma InforMatrix GmbH. Das Werkzeug ist sehr einfach gehalten und unterstützt daher nur grundlegende Funktionalitäten. Badboy: Badboy ist eine von der Firma Badboy Software entwickelte, schlanke Capture & Replay Testsoftware. Da sie einen eignen Browser zur Ausführung der Testfälle besitzt, kann keine Browserkompatibilität garantiert werden. evalid: evalid von der Firma Software Research, Inc. unterstützt nur Tests mittels Microsoft Internet Explorer, da es in den installierten Internet Explorer integriert wird. Daher können auch alle Funktionen, die der Internet Explorer bietet, genützt werden. QA Wizard Pro: Die Firma Seapine Software bietet in ihrem Portfolio unter anderem dem QA Wizzard Pro für Funktions- und Regressionstests an. Da sie weitere Produkte im Test-Lifecycle anbietet, können Daten aus anderen Produkten in den Testfällen wiederverwendet werden. Test4Q: Test4Q ist ein Host-orientiertes Capture-/Replay Tool, das speziell CICS-Transaktionen verarbeiten kann. Eine Fülle weiterer Funktionalitäten auch für den Batchablauf stehen ebenfalls zur Verfügung. Unter bestimmten Voraussetzungen ist auch eine (Teil)automatisierung zur Erstellung der Testscripte (ohne eine vorherige Aufzeichnung) möglich. Prof. A. Müller, HS KL Software Engineering 2015 24
http://www.stickyminds.com/ Welcome to StickyMinds.com one of the first and most popular online communities for software development professionals. StickyMinds.com is dedicated to improving software quality throughout the software development lifecycle. Written by industry experts, StickyMinds.com covers topics ranging from agile testing to mobile and cloud computing and everything in between. You ll also find blog postings, software testing jobs, Q&A and more. Membership is free and includes a complimentary digital subscription to Better Software magazine. To get started, simply click Join in the upper right corner, and you ll be plugged in for the latest in software testing and quality assurance Prof. A. Müller, HS KL Software Engineering 2015 25