2025-12-17 17:45:18 +01:00
|
|
|
#run_tests.py
|
2025-12-02 20:55:51 +01:00
|
|
|
import sys
|
|
|
|
|
import os
|
|
|
|
|
import unittest
|
2025-12-17 17:45:18 +01:00
|
|
|
import datetime
|
|
|
|
|
import inspect
|
|
|
|
|
|
|
|
|
|
# Farben
|
|
|
|
|
RED = "\033[91m"
|
|
|
|
|
YELLOW = "\033[93m"
|
|
|
|
|
GREEN = "\033[92m"
|
|
|
|
|
CYAN = "\033[96m"
|
|
|
|
|
MAGENTA = "\033[95m"
|
|
|
|
|
RESET = "\033[0m"
|
|
|
|
|
|
|
|
|
|
# Globaler Testzähler
|
|
|
|
|
GLOBAL_TEST_COUNTER = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
# Eigene TestResult-Klasse (färbt Fehler/Skipped/OK)
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
class ColoredTestResult(unittest.TextTestResult):
|
|
|
|
|
|
|
|
|
|
def startTest(self, test):
|
|
|
|
|
"""Vor jedem Test eine Nummer ausgeben."""
|
|
|
|
|
global GLOBAL_TEST_COUNTER
|
|
|
|
|
GLOBAL_TEST_COUNTER += 1
|
|
|
|
|
self.stream.write(f"{CYAN}[Test {GLOBAL_TEST_COUNTER}]{RESET}\n")
|
|
|
|
|
super().startTest(test)
|
|
|
|
|
|
|
|
|
|
def startTestRun(self):
|
|
|
|
|
"""Wird einmal zu Beginn des gesamten Testlaufs ausgeführt."""
|
|
|
|
|
super().startTestRun()
|
|
|
|
|
|
|
|
|
|
def startTestClass(self, test):
|
|
|
|
|
"""Wird aufgerufen, wenn eine neue Testklasse beginnt."""
|
|
|
|
|
cls = test.__class__
|
|
|
|
|
file = inspect.getfile(cls)
|
|
|
|
|
filename = os.path.basename(file)
|
|
|
|
|
|
|
|
|
|
self.stream.write(
|
|
|
|
|
f"\n{MAGENTA}{'='*70}\n"
|
|
|
|
|
f"Starte Testklasse: {filename} → {cls.__name__}\n"
|
|
|
|
|
f"{'='*70}{RESET}\n"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def addError(self, test, err):
|
|
|
|
|
super().addError(test, err)
|
|
|
|
|
self.stream.write(f"{RED}ERROR{RESET}\n")
|
|
|
|
|
|
|
|
|
|
def addFailure(self, test, err):
|
|
|
|
|
super().addFailure(test, err)
|
|
|
|
|
self.stream.write(f"{RED}FAILURE{RESET}\n")
|
|
|
|
|
|
|
|
|
|
def addSkip(self, test, reason):
|
|
|
|
|
super().addSkip(test, reason)
|
|
|
|
|
self.stream.write(f"{YELLOW}SKIPPED{RESET}: {reason}\n")
|
|
|
|
|
|
|
|
|
|
# unittest ruft diese Methode nicht automatisch auf → wir patchen es unten
|
|
|
|
|
def addSuccess(self, test):
|
|
|
|
|
super().addSuccess(test)
|
|
|
|
|
self.stream.write(f"{GREEN}OK{RESET}\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
# Eigener TestRunner, der unser ColoredTestResult nutzt
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
class ColoredTestRunner(unittest.TextTestRunner):
|
|
|
|
|
resultclass = ColoredTestResult
|
|
|
|
|
|
|
|
|
|
def _makeResult(self):
|
|
|
|
|
result = super()._makeResult()
|
|
|
|
|
|
|
|
|
|
# Patch: unittest ruft startTestClass nicht automatisch auf
|
|
|
|
|
original_start_test = result.startTest
|
|
|
|
|
|
|
|
|
|
def patched_start_test(test):
|
|
|
|
|
# Wenn neue Klasse → Kopf ausgeben
|
|
|
|
|
if not hasattr(result, "_last_test_class") or \
|
|
|
|
|
result._last_test_class != test.__class__:
|
|
|
|
|
result.startTestClass(test)
|
|
|
|
|
result._last_test_class = test.__class__
|
|
|
|
|
|
|
|
|
|
original_start_test(test)
|
|
|
|
|
|
|
|
|
|
result.startTest = patched_start_test
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
# Testlauf starten
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
print("\n" + "="*70)
|
|
|
|
|
print(f"{CYAN}Testlauf gestartet am: {datetime.datetime.now():%Y-%m-%d %H:%M:%S}{RESET}")
|
|
|
|
|
print("="*70 + "\n")
|
2025-12-02 20:55:51 +01:00
|
|
|
|
|
|
|
|
# Projekt-Root dem Suchpfad hinzufügen
|
|
|
|
|
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
|
|
|
|
if project_root not in sys.path:
|
|
|
|
|
sys.path.insert(0, project_root)
|
|
|
|
|
|
2025-12-17 17:45:18 +01:00
|
|
|
|
2025-12-02 20:55:51 +01:00
|
|
|
def main():
|
|
|
|
|
loader = unittest.TestLoader()
|
|
|
|
|
suite = unittest.TestSuite()
|
|
|
|
|
|
|
|
|
|
test_modules = [
|
|
|
|
|
"test_dateipruefer",
|
|
|
|
|
"test_stilpruefer",
|
|
|
|
|
"test_linkpruefer",
|
2025-12-17 17:45:18 +01:00
|
|
|
"test_qt_compat",
|
|
|
|
|
"test_pruefmanager",
|
2025-12-02 20:55:51 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
for mod_name in test_modules:
|
|
|
|
|
mod = __import__(mod_name)
|
|
|
|
|
suite.addTests(loader.loadTestsFromModule(mod))
|
|
|
|
|
|
2025-12-17 17:45:18 +01:00
|
|
|
runner = ColoredTestRunner(verbosity=2)
|
2025-12-02 20:55:51 +01:00
|
|
|
runner.run(suite)
|
|
|
|
|
|
2025-12-17 17:45:18 +01:00
|
|
|
|
2025-12-02 20:55:51 +01:00
|
|
|
if __name__ == "__main__":
|
|
|
|
|
main()
|