<?xml version="1.0" encoding="UTF-8"?> | |||||
<module type="JAVA_MODULE" version="4"> | |||||
<component name="NewModuleRootManager" inherit-compiler-output="true"> | |||||
<exclude-output /> | |||||
<content url="file://$MODULE_DIR$" /> | |||||
<orderEntry type="inheritedJdk" /> | |||||
<orderEntry type="sourceFolder" forTests="false" /> | |||||
</component> | |||||
</module> |
<component name="libraryTable"> | |||||
<library name="jars"> | |||||
<CLASSES> | |||||
<root url="jar://$PROJECT_DIR$/jars/junit-4.12.jar!/" /> | |||||
<root url="jar://$PROJECT_DIR$/jars/hamcrest-core-1.3.jar!/" /> | |||||
</CLASSES> | |||||
<JAVADOC /> | |||||
<SOURCES /> | |||||
</library> | |||||
</component> |
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="ProjectRootManager" version="2" project-jdk-name="openjdk-17" project-jdk-type="JavaSDK"> | |||||
<output url="file://$PROJECT_DIR$/out" /> | |||||
</component> | |||||
</project> |
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="ProjectModuleManager"> | |||||
<modules> | |||||
<module fileurl="file://$PROJECT_DIR$/TriangleCheckerAssignment.iml" filepath="$PROJECT_DIR$/TriangleCheckerAssignment.iml" /> | |||||
</modules> | |||||
</component> | |||||
</project> |
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="VcsDirectoryMappings"> | |||||
<mapping directory="" vcs="Git" /> | |||||
</component> | |||||
</project> |
# Programmieren 3 | |||||
## Assignment "TDD Einführung" | |||||
### Ausgangssituation | |||||
#### Test Driven Development (TDD) | |||||
Bei TDD gilt die Regel: Produktivcode darf erst geschrieben werden, wenn | |||||
ein Test vorliegt, der scheitert. Und auch dann soll nur gerade so | |||||
viel Code geschrieben werden, um den Testfall (und alle anderen Tests) | |||||
erfolgreich ausführen zu können. | |||||
#### Struktur des Assignments | |||||
Das Assignment besteht aus zwei Java-Klassen: | |||||
- <code>TriangleChecker</code> enthält den Produktivcode | |||||
- <code>TriangleCheckerTest</code> enthält die Tests | |||||
Mit Hilfe von TDD soll insbesondere die Methode | |||||
<code> | |||||
checkTriangle(float a, float b, float c) | |||||
</code> | |||||
entwickelt werden. Diese Methode hat die Aufgabe, anhand | |||||
der übergebenen drei Seitenlängen zu entscheiden, ob es | |||||
sich um ein normales, ein gleichschenkliges, ein | |||||
gleichseitiges oder gar kein Dreieck handelt. | |||||
### Aufgabenstellung | |||||
#### Normales Dreieck | |||||
Mit dem Assignment kommt ein erster Testfall, | |||||
der überprüft, ob ein normales Dreieck richtig erkannt | |||||
wird. Sorgen Sie dafür, dass der Testfall nicht mehr scheitert. | |||||
Achten Sie darauf, dass Sie nicht mehr implementieren, als | |||||
zur Lösung dieses Testfalls notwendig ist. Weitere | |||||
Fälle müssen noch nicht erkannt werden. | |||||
#### Gleichseitiges Dreieck | |||||
Erstellen Sie nun einen Testfall, der überprüft, | |||||
ob ein gleichseitiges Dreieck erkannt wird. | |||||
Da Sie bisher nur normale Dreiecke identifizieren, | |||||
wird dieser Testfall zunächst scheitern. | |||||
Nehmen Sie nun minimale Änderungen am Produktivcode vor, | |||||
so dass beide Testfälle fehlerfrei ausgeführt werden. | |||||
#### Kein Dreieck | |||||
Es gibt Zahlenkombinationen, die nicht zu einem | |||||
Dreieck passen (z.B. negative Zahlen oder | |||||
eine überlange Seite, so dass die anderen beiden | |||||
Seiten das Dreieck nicht abschließen können). | |||||
Erstellen Sie jeweils eigene Testfälle für diese | |||||
Art von Zahlenkombinationen. Das sind mindestens | |||||
6 weitere Testfälle (warum?). | |||||
Korrigieren Sie anschließend den Produktivcode, | |||||
so dass alle Tests durchlaufen. | |||||
#### Gleichschenkliges Dreieck | |||||
Schließlich sollen noch gleichschenklige Dreiecke | |||||
erkannt werden. Dabei soll die | |||||
Methode stets die genaueste Information | |||||
zurückliefern, d.h. | |||||
- bei einem gleichseitigen Dreieck *EQUILATERAL*, auch wenn | |||||
ein gleichseitiges Dreieck natürlich auch gleichschenklig | |||||
ist. | |||||
- bei einem gleichschenkligem Dreieck *ISOSCELES*, auch wenn | |||||
ein gleichschenkliges Dreieck natürlich auch ein | |||||
normales Dreieck ist. | |||||
Verwenden Sie auch hier die TDD-Vorgehensweise. |
<?xml version="1.0" encoding="UTF-8"?> | |||||
<module type="JAVA_MODULE" version="4"> | |||||
<component name="NewModuleRootManager" inherit-compiler-output="true"> | |||||
<exclude-output /> | |||||
<content url="file://$MODULE_DIR$"> | |||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> | |||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" /> | |||||
</content> | |||||
<orderEntry type="inheritedJdk" /> | |||||
<orderEntry type="sourceFolder" forTests="false" /> | |||||
<orderEntry type="library" name="jars" level="project" /> | |||||
</component> | |||||
</module> |
<?xml version="1.0" encoding="UTF-8"?> | |||||
<module type="JAVA_MODULE" version="4"> | |||||
<component name="NewModuleRootManager" inherit-compiler-output="true"> | |||||
<exclude-output /> | |||||
<content url="file://$MODULE_DIR$"> | |||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> | |||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" /> | |||||
</content> | |||||
<orderEntry type="inheritedJdk" /> | |||||
<orderEntry type="sourceFolder" forTests="false" /> | |||||
<orderEntry type="library" name="jars" level="project" /> | |||||
</component> | |||||
</module> |
import java.util.Scanner; | |||||
public class TriangleChecker { | |||||
public enum TriangleType { | |||||
NONE, | |||||
NORMAL, | |||||
ISOSCELES, // Gleichschenklig | |||||
EQUILATERAL // Gleichseitig | |||||
} | |||||
public static void main(String[] args) { | |||||
Scanner s = new Scanner(System.in); | |||||
System.out.println("Geben Sie die Seitenlängen ein."); | |||||
float a = enterFloat(s, "a: "); | |||||
float b = enterFloat(s, "b: "); | |||||
float c = enterFloat(s, "c: "); | |||||
s.close(); | |||||
printAnalysis(a, b, c); | |||||
} | |||||
// Eingabe einer Seitenlänge | |||||
private static float enterFloat(Scanner s, String prompt) { | |||||
System.out.print(prompt); | |||||
return s.nextFloat(); | |||||
} | |||||
// Ausgabe der ermittelten Dreiecksart | |||||
private static void printAnalysis(float a, float b, float c) { | |||||
TriangleType type = checkTriangle(a, b, c); | |||||
switch (type) { | |||||
case NONE: | |||||
System.out.println("Kein Dreieck"); | |||||
break; | |||||
case NORMAL: | |||||
System.out.println("Dreieck"); | |||||
break; | |||||
case ISOSCELES: | |||||
System.out.println("Gleichschenkliges Dreieck"); | |||||
break; | |||||
case EQUILATERAL: | |||||
System.out.println("Gleichseitiges Dreieck"); | |||||
break; | |||||
} | |||||
} | |||||
// Analyse der Dreiecksart | |||||
public static TriangleType checkTriangle(float a, float b, float c) { | |||||
if (a <= 0 || b <= 0 || c <= 0 || a + b < c || a + c < b || b + c < a) | |||||
// kein Dreieck | |||||
return TriangleType.NONE; | |||||
if (a + b > c || a + c > b || b + c > a) { | |||||
// gleichseitiges Dreieck | |||||
if (a == b && b == c) { | |||||
return TriangleType.EQUILATERAL; | |||||
} | |||||
if (a == b || b == c || a == c) { | |||||
// gleichschenkliges Dreieck | |||||
return TriangleType.ISOSCELES; | |||||
} | |||||
// normales Dreieck | |||||
return TriangleType.NORMAL; | |||||
} | |||||
// kein Dreieck | |||||
return TriangleType.NONE; | |||||
} | |||||
} |
import org.junit.Test; | |||||
import static org.junit.Assert.*; | |||||
public class TriangleCheckerTest { | |||||
@Test | |||||
public void testValidTriangle() { | |||||
// Arrange | |||||
float a = 2; | |||||
float b = 3; | |||||
float c = 4; | |||||
// Act | |||||
TriangleChecker.TriangleType type = TriangleChecker.checkTriangle(a, b, c); | |||||
// Assert | |||||
assertEquals(TriangleChecker.TriangleType.NORMAL, type); | |||||
} | |||||
// gleichschenkliges Dreieck | |||||
@Test | |||||
public void testISOSCELESTriangle() { | |||||
// Arrange | |||||
float a = 4; | |||||
float b = 4; | |||||
float c = 3; | |||||
// Act | |||||
TriangleChecker.TriangleType type = TriangleChecker.checkTriangle(a, b, c); | |||||
// Assert | |||||
assertEquals(TriangleChecker.TriangleType.ISOSCELES, type); | |||||
} | |||||
// gleichseitiges Dreieck | |||||
@Test | |||||
public void testEQUILATERALTriangle() { | |||||
// Arrange | |||||
float a = 4; | |||||
float b = 4; | |||||
float c = 4; | |||||
// Act | |||||
TriangleChecker.TriangleType type = TriangleChecker.checkTriangle(a, b, c); | |||||
// Assert | |||||
assertEquals(TriangleChecker.TriangleType.EQUILATERAL, type); | |||||
} | |||||
// gleichseitiges Dreieck | |||||
@Test | |||||
public void testNoTriangle1() { | |||||
// Arrange | |||||
float a = 100; | |||||
float b = 1; | |||||
float c = 1; | |||||
// Act | |||||
TriangleChecker.TriangleType type = TriangleChecker.checkTriangle(a, b, c); | |||||
// Assert | |||||
assertEquals(TriangleChecker.TriangleType.NONE, type); | |||||
} | |||||
// gleichseitiges Dreieck | |||||
@Test | |||||
public void testNoTriangle2() { | |||||
// Arrange | |||||
float a = -3; | |||||
float b = -3; | |||||
float c = -3; | |||||
// Act | |||||
TriangleChecker.TriangleType type = TriangleChecker.checkTriangle(a, b, c); | |||||
// Assert | |||||
assertEquals(TriangleChecker.TriangleType.NONE, type); | |||||
} | |||||
} |