160 lines
8.4 KiB
Python
160 lines
8.4 KiB
Python
import unittest
|
|
import sys
|
|
from pathlib import Path
|
|
import importlib.util
|
|
|
|
# Pfad zum aktuellen Kapitelverzeichnis
|
|
CHAPTER_DIR = Path(__file__).parent
|
|
|
|
|
|
def lade_modul(modul_name="aufgabe"):
|
|
"""Lädt das Modul (aufgabe oder musterloesung) isoliert aus dem Kapitelverzeichnis."""
|
|
dateipfad = CHAPTER_DIR / f"{modul_name}.py"
|
|
if not dateipfad.exists():
|
|
raise FileNotFoundError(f"Datei '{dateipfad}' wurde nicht gefunden.")
|
|
spec = importlib.util.spec_from_file_location(f"g04_{modul_name}", dateipfad)
|
|
modul = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(modul)
|
|
return modul
|
|
|
|
|
|
class TestKapitelG04(unittest.TestCase):
|
|
"""
|
|
Testsuite für Kapitel G04: Verzweigungen & Bedingungen
|
|
Überprüft if/elif/else-Verzweigungen, Grenzwerte und logische Operatoren.
|
|
"""
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.target_modul = getattr(cls, "modul_name", "aufgabe")
|
|
try:
|
|
cls.mod = lade_modul(cls.target_modul)
|
|
except SyntaxError as e:
|
|
cls.mod = None
|
|
cls.import_error = f"SyntaxError in '{cls.target_modul}.py': {e}"
|
|
except Exception as e:
|
|
cls.mod = None
|
|
cls.import_error = f"Fehler beim Laden von '{cls.target_modul}.py': {e}"
|
|
|
|
def _get_modul(self):
|
|
if getattr(self, "mod", None) is None:
|
|
err = getattr(self, "import_error", f"{self.target_modul}.py konnte nicht geladen werden")
|
|
self.fail(f"❌ {err}")
|
|
return self.mod
|
|
|
|
def test_01_ticket_preis_alle_tarife(self):
|
|
"""Prüft TODO 1: ticket_preis(alter, ist_student) für alle Altersgruppen."""
|
|
mod = self._get_modul()
|
|
self.assertTrue(
|
|
hasattr(mod, "ticket_preis"),
|
|
"Fehler: Funktion 'ticket_preis' fehlt in aufgabe.py!"
|
|
)
|
|
|
|
# Kindertarif (< 12 Jahre): 6.00 €
|
|
self.assertEqual(mod.ticket_preis(5, False), 6.0, "Alter 5 sollte 6.00 € kosten (Kindertarif)!")
|
|
self.assertEqual(mod.ticket_preis(11, False), 6.0, "Alter 11 sollte 6.00 € kosten (Kindertarif)!")
|
|
self.assertEqual(mod.ticket_preis(11, True), 6.0, "Kinder zahlen immer 6.00 €!")
|
|
|
|
# Seniorentarif (>= 65 Jahre): 8.50 €
|
|
self.assertEqual(mod.ticket_preis(65, False), 8.5, "Alter 65 sollte 8.50 € kosten (Seniorentarif)!")
|
|
self.assertEqual(mod.ticket_preis(80, False), 8.5, "Alter 80 sollte 8.50 € kosten (Seniorentarif)!")
|
|
self.assertEqual(mod.ticket_preis(70, True), 8.5, "Senioren ab 65 zahlen 8.50 €!")
|
|
|
|
# Studenten- / Ermäßigungstarif (12 <= alter < 65 und ist_student == True): 9.50 €
|
|
self.assertEqual(mod.ticket_preis(12, True), 9.5, "Schüler/Student mit 12 Jahren sollte 9.50 € kosten!")
|
|
self.assertEqual(mod.ticket_preis(22, True), 9.5, "Student mit 22 Jahren sollte 9.50 € kosten!")
|
|
self.assertEqual(mod.ticket_preis(64, True), 9.5, "Student mit 64 Jahren sollte 9.50 € kosten!")
|
|
|
|
# Regulärer Erwachsenentarif (12 <= alter < 65 und ist_student == False): 12.00 €
|
|
self.assertEqual(mod.ticket_preis(12, False), 12.0, "Regulärer Preis ab 12 Jahren ohne Ermäßigung ist 12.00 €!")
|
|
self.assertEqual(mod.ticket_preis(35, False), 12.0, "Erwachsener (35) ohne Ermäßigung sollte 12.00 € zahlen!")
|
|
self.assertEqual(mod.ticket_preis(64, False), 12.0, "Erwachsener (64) ohne Ermäßigung sollte 12.00 € zahlen!")
|
|
|
|
def test_02_schulnote_text_grenzwerte(self):
|
|
"""Prüft TODO 2: schulnote_text(punkte) inklusive aller Grenzwerte."""
|
|
mod = self._get_modul()
|
|
self.assertTrue(
|
|
hasattr(mod, "schulnote_text"),
|
|
"Fehler: Funktion 'schulnote_text' fehlt in aufgabe.py!"
|
|
)
|
|
|
|
# 90..100: "Sehr gut"
|
|
self.assertEqual(mod.schulnote_text(100), "Sehr gut", "100 Punkte müssen 'Sehr gut' ergeben!")
|
|
self.assertEqual(mod.schulnote_text(90), "Sehr gut", "Genau 90 Punkte müssen 'Sehr gut' ergeben (Grenzwert)!")
|
|
|
|
# 75..89: "Gut"
|
|
self.assertEqual(mod.schulnote_text(89), "Gut", "89 Punkte müssen 'Gut' ergeben!")
|
|
self.assertEqual(mod.schulnote_text(75), "Gut", "Genau 75 Punkte müssen 'Gut' ergeben (Grenzwert)!")
|
|
|
|
# 60..74: "Befriedigend"
|
|
self.assertEqual(mod.schulnote_text(74), "Befriedigend", "74 Punkte müssen 'Befriedigend' ergeben!")
|
|
self.assertEqual(mod.schulnote_text(60), "Befriedigend", "Genau 60 Punkte müssen 'Befriedigend' ergeben (Grenzwert)!")
|
|
|
|
# 50..59: "Genügend"
|
|
self.assertEqual(mod.schulnote_text(59), "Genügend", "59 Punkte müssen 'Genügend' ergeben!")
|
|
self.assertEqual(mod.schulnote_text(50), "Genügend", "Genau 50 Punkte müssen 'Genügend' ergeben (Grenzwert)!")
|
|
|
|
# 0..49: "Nicht genügend"
|
|
self.assertEqual(mod.schulnote_text(49), "Nicht genügend", "49 Punkte müssen 'Nicht genügend' ergeben!")
|
|
self.assertEqual(mod.schulnote_text(0), "Nicht genügend", "0 Punkte müssen 'Nicht genügend' ergeben!")
|
|
|
|
# Ungültig (< 0 oder > 100)
|
|
self.assertEqual(mod.schulnote_text(-1), "Ungültige Punktezahl", "-1 Punkt muss 'Ungültige Punktezahl' ergeben!")
|
|
self.assertEqual(mod.schulnote_text(101), "Ungültige Punktezahl", "101 Punkte müssen 'Ungültige Punktezahl' ergeben!")
|
|
|
|
def test_03_ist_schaltjahr_regeln(self):
|
|
"""Prüft TODO 3: ist_schaltjahr(jahr) mit allen Gregorianischen Ausnahmen."""
|
|
mod = self._get_modul()
|
|
self.assertTrue(
|
|
hasattr(mod, "ist_schaltjahr"),
|
|
"Fehler: Funktion 'ist_schaltjahr' fehlt in aufgabe.py!"
|
|
)
|
|
|
|
# Normale Schaltjahre (durch 4 teilbar, nicht durch 100):
|
|
self.assertTrue(mod.ist_schaltjahr(2024), "2024 ist ein Schaltjahr (durch 4 teilbar)!")
|
|
self.assertTrue(mod.ist_schaltjahr(2020), "2020 ist ein Schaltjahr!")
|
|
self.assertTrue(mod.ist_schaltjahr(2016), "2016 ist ein Schaltjahr!")
|
|
|
|
# Normale Nicht-Schaltjahre (nicht durch 4 teilbar):
|
|
self.assertFalse(mod.ist_schaltjahr(2023), "2023 ist kein Schaltjahr!")
|
|
self.assertFalse(mod.ist_schaltjahr(2025), "2025 ist kein Schaltjahr!")
|
|
|
|
# Säkularjahre / Jahrhundert-Regel:
|
|
# Durch 100 teilbar, aber NICHT durch 400 -> KEIN Schaltjahr!
|
|
self.assertFalse(mod.ist_schaltjahr(1900), "1900 ist KEIN Schaltjahr (durch 100 teilbar, aber nicht durch 400)!")
|
|
self.assertFalse(mod.ist_schaltjahr(2100), "2100 ist KEIN Schaltjahr (durch 100 teilbar, aber nicht durch 400)!")
|
|
self.assertFalse(mod.ist_schaltjahr(1800), "1800 ist KEIN Schaltjahr!")
|
|
|
|
# 400er-Regel:
|
|
# Durch 400 teilbar -> IST ein Schaltjahr!
|
|
self.assertTrue(mod.ist_schaltjahr(2000), "2000 IST ein Schaltjahr (durch 400 teilbar)!")
|
|
self.assertTrue(mod.ist_schaltjahr(2400), "2400 IST ein Schaltjahr (durch 400 teilbar)!")
|
|
self.assertTrue(mod.ist_schaltjahr(1600), "1600 IST ein Schaltjahr (durch 400 teilbar)!")
|
|
|
|
def test_04_kann_achterbahn_fahren(self):
|
|
"""Prüft TODO 4: kann_achterbahn_fahren(groesse_cm, begleitung_erwachsen)."""
|
|
mod = self._get_modul()
|
|
self.assertTrue(
|
|
hasattr(mod, "kann_achterbahn_fahren"),
|
|
"Fehler: Funktion 'kann_achterbahn_fahren' fehlt in aufgabe.py!"
|
|
)
|
|
|
|
# Ab 140 cm: Immer erlaubt (auch ohne Begleitung)
|
|
self.assertTrue(mod.kann_achterbahn_fahren(140, False), "Genau 140 cm darf alleine fahren!")
|
|
self.assertTrue(mod.kann_achterbahn_fahren(155, False), "155 cm darf alleine fahren!")
|
|
self.assertTrue(mod.kann_achterbahn_fahren(140, True), "140 cm mit Begleitung darf natürlich auch fahren!")
|
|
|
|
# 120 bis 139 cm: NUR mit erwachsener Begleitung
|
|
self.assertTrue(mod.kann_achterbahn_fahren(120, True), "120 cm mit Begleitung ist erlaubt!")
|
|
self.assertTrue(mod.kann_achterbahn_fahren(135, True), "135 cm mit Begleitung ist erlaubt!")
|
|
self.assertFalse(mod.kann_achterbahn_fahren(120, False), "120 cm OHNE Begleitung ist verboten!")
|
|
self.assertFalse(mod.kann_achterbahn_fahren(139, False), "139 cm OHNE Begleitung ist verboten!")
|
|
|
|
# Unter 120 cm: Grundsätzlich verboten (auch mit Begleitung)
|
|
self.assertFalse(mod.kann_achterbahn_fahren(119, True), "119 cm ist zu klein, auch mit Begleitung!")
|
|
self.assertFalse(mod.kann_achterbahn_fahren(119, False), "119 cm ohne Begleitung ist verboten!")
|
|
self.assertFalse(mod.kann_achterbahn_fahren(95, True), "95 cm ist zu klein!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main(verbosity=2)
|