UE zu SW 2 Frameworks / Klassenbibliotheken 1 • Wie unterscheidet sich die Wiederverwendung bei Frameworks und Klassenbibliotheken? • Wie kann es ausgebaut werden? • Was ist ein Framework? Selbsttest: Frameworks und Klassenbibliotheken UE zu SW 2 Frameworks / Klassenbibliotheken > java -cp .;junit3\junit.jar junit.swingui.TestRunner MyTests > java -cp .;junit3\junit.jar junit.textui.TestRunner MyTests – Ausführen eigener Tests: > javac -classpath .;junit3\junit.jar MyTests.java oder – Compilieren eigener Testklassen (von junit.framework.TestCase abgeleitet): > cd junit3 > java -cp .;junit3\junit.jar junit.textui.TestRunner junit.samples.AllTests .......................................................................................... Time: 1,202 OK (90 Tests) – junit3\junit.jar muss im CLASSPATH sein! • Installation testen: (siehe auch junit3\readme.html) • junit3.8.1.zip entpacken (in bel. Verzeichnis, hier Pfad = junit3) – Installation: • auch für andere Sprachen (xprogramming.com/software.htm) • Framework zum Testen von Java-Software (junit.org) JUnit 2 UE zu SW 2 } Frameworks / Klassenbibliotheken public ComplexNumber (double r, double im) { this.r = r; this.im = im; } public class ComplexNumber { private double r, im; // real and imaginary part ComplexNumber (v0) 3 UE zu SW 2 } Frameworks / Klassenbibliotheken protected void setUp () { c0 = new ComplexNumber(0,0); c1 = new ComplexNumber(1,0); c2 = new ComplexNumber(0,1); c3 = new ComplexNumber(-7,2); c4 = new ComplexNumber(2.3,-3); c5 = new ComplexNumber(-3.4, -17.32); } // a first test case: testing the equals method public void testEquals () { test erwartetes Ergebnis assertEquals("Same object", c1, c1); assertEquals tatsächlicher Wert assertEquals("Same value", c3, new ComplexNumber(-7,2)); assertEquals assertTrue("c1 != c2", !c1.equals(c2)); assertTrue assertTrue("Not equal to 0!", !c2.equals(c0)); assertTrue assertTrue("Real part has different sign", assertTrue !c3.equals(new ComplexNumber(7,2))); } import junit.framework.TestCase; public class ComplexNumberTest extends TestCase { ComplexNumber c0, c1, c2, c3, c4, c5; ComplexNumberTest 4 UE zu SW 2 5 Programm wurde mit einer Exception abgebrochen. Errors: 0 Frameworks / Klassenbibliotheken Failures: 1, Ein Assert schlug fehl. FAILURES!!! Tests run: 1, > java -cp .;junit3\junit.jar junit.textui.TestRunner ComplexNumberTest .F Time: 0,06 There was 1 failure: 1) testEquals(ComplexNumberTest) junit.framework.AssertionFailedError: Same value expected:<ComplexNumber@30c221> but was:<ComplexNumber@19298d> at ComplexNumberTest.testEquals(ComplexNumberTest.java:14) at ... Testing ComplexNumber (v0) UE zu SW 2 } Frameworks / Klassenbibliotheken public boolean equals (Object o) { if (super.equals(o)) return true; // same object if (o instanceof ComplexNumber) { ComplexNumber c = (ComplexNumber) o; return r == c.r && im == c.im; } return false; } public ComplexNumber (double r, double im) { this.r = r; this.im = im; } public class ComplexNumber { private double r, im; // real and imaginary part ComplexNumber (v1) 6 UE zu SW 2 Frameworks / Klassenbibliotheken 7 > javaw -cp .;junit3\junit.jar junit.swingui.TestRunner ComplexNumberTest Testing ComplexNumber (v1) UE zu SW 2 Java-Beispiel: Ausgabe: Frameworks / Klassenbibliotheken System.out.println(4.4 + " – " + 3.4 + " = " + (4.4 - 3.4)); 4.4 - 3.4 = 1.0000000000000004 Insbesondere gilt: (a + b) + c ≠ a + (b + c) Hinweis: Gleitkommazahlen dienen der näherungsweisen Repräsentation von reellen Zahlen im Computer. Das bedeutet auch das Operationen mit ihnen näherungsweise (=ungenaue!) Ergebnisse liefern. 2. Erweitern Sie die Klasse ComplexNumber um ein Methode zum Addieren von komplexen Zahlen. Testen Sie die neue Version mit den zuvor geschriebenen Testfällen. 1. Erweitern Sie die Klasse ComplexNumberTest um einen Testfall testAdd(), der die Addition zweier komplexer Zahlen überprüft. Programmierbeispiel 8 UE zu SW 2 } Frameworks / Klassenbibliotheken public void testAdd () { assertEquals(new ComplexNumber(1,1), c1.add(c2)); assertEquals(new ComplexNumber(1,1), c2.add(c1)); assertEquals(c5, c5.add(c0)); assertEquals(c5, c0.add(c5)); assertEquals(new ComplexNumber(-4.7,-1), c3.add(c4)); assertEquals(c0, c3.add(new ComplexNumber(7,-2))); assertEquals(c1, c5.add(new ComplexNumber(4.4,17.32))); assertEquals(c2, c4.add(new ComplexNumber(-2.3,4))); } public void testEquals () { ... } protected void setUp () { ... } public ComplexNumberTest (String name) { super(name); } public class ComplexNumberTest extends TestCase { ComplexNumber c0, c1, c2, c3, c4, c5; ComplexNumberTest (v2) 9 UE zu SW 2 } Frameworks / Klassenbibliotheken public ComplexNumber add (ComplexNumber c) { return new ComplexNumber(r + c.r, im + c.im); } public boolean equals (Object o) { ... } public ComplexNumber (double r, double im) { this.r = r; this.im = im; } public class ComplexNumber { private double r, im; // real and imaginary part ComplexNumber (v2) 10 UE zu SW 2 FAILURES!!! Tests run: 2, Errors: 0 Frameworks / Klassenbibliotheken Failures: 1, > java -cp .;junit3\junit.jar junit.textui.TestRunner ComplexNumberTest .F Time: 0,02 There was 1 failure: 1) testAdd(ComplexNumberTest) junit.framework.AssertionFailedError: expected:<1> but was:<1.0000000000000004> at ComplexNumberTest.testAdd(ComplexNumberTest.java:41) at ... Testing ComplexNumber (v2) 11 UE zu SW 2 } Frameworks / Klassenbibliotheken public ComplexNumber add (ComplexNumber c) { return new ComplexNumber(r + c.r, im + c.im); } public boolean equals (Object o) { if (super.equals(o)) return true; // same object if (o instanceof ComplexNumber) { ComplexNumber c = (ComplexNumber) o; return isApproxEqual(r,c.r) && isApproxEqual(im,c.im); } return false; } 12 private static boolean isApproxEqual (double d1, double d2) { return Math.abs(d1 - d2) < epsilon; } public class ComplexNumber { static double epsilon = 0.0000000001;// max. precision private double r, im; // real and imaginary part ComplexNumber (v3)