forked from AG_QGIS/Plugin_SN_Plan41
149 lines
3.7 KiB
Python
149 lines
3.7 KiB
Python
|
|
"""
|
||
|
|
sn_plan41/test/run_tests.py
|
||
|
|
|
||
|
|
Zentraler Test-Runner für sn_plan41.
|
||
|
|
Wrapper-konform, QGIS-unabhängig, CI- und IDE-fähig.
|
||
|
|
"""
|
||
|
|
|
||
|
|
import unittest
|
||
|
|
import datetime
|
||
|
|
import inspect
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
# Plugin-Roots bestimmen
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
|
||
|
|
THIS_FILE = Path(__file__).resolve()
|
||
|
|
|
||
|
|
# .../plugins/sn_plan41
|
||
|
|
SN_PLAN41_ROOT = THIS_FILE.parents[1]
|
||
|
|
# .../plugins/sn_basis
|
||
|
|
SN_BASIS_ROOT = SN_PLAN41_ROOT.parent / "sn_basis"
|
||
|
|
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
# sys.path Bootstrap
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
|
||
|
|
for path in (SN_PLAN41_ROOT, SN_BASIS_ROOT):
|
||
|
|
path_str = str(path)
|
||
|
|
if path_str not in sys.path:
|
||
|
|
sys.path.insert(0, path_str)
|
||
|
|
|
||
|
|
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
# Farben
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
|
||
|
|
RED = "\033[91m"
|
||
|
|
YELLOW = "\033[93m"
|
||
|
|
GREEN = "\033[92m"
|
||
|
|
CYAN = "\033[96m"
|
||
|
|
MAGENTA = "\033[95m"
|
||
|
|
RESET = "\033[0m"
|
||
|
|
|
||
|
|
GLOBAL_TEST_COUNTER = 0
|
||
|
|
|
||
|
|
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
# Farbige TestResult-Klasse
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
|
||
|
|
class ColoredTestResult(unittest.TextTestResult):
|
||
|
|
|
||
|
|
_last_test_class = None
|
||
|
|
|
||
|
|
def startTest(self, test):
|
||
|
|
global GLOBAL_TEST_COUNTER
|
||
|
|
GLOBAL_TEST_COUNTER += 1
|
||
|
|
self.stream.write(f"{CYAN}[Test {GLOBAL_TEST_COUNTER}]{RESET}\n")
|
||
|
|
super().startTest(test)
|
||
|
|
|
||
|
|
def startTestClass(self, test):
|
||
|
|
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")
|
||
|
|
|
||
|
|
def addSuccess(self, test):
|
||
|
|
super().addSuccess(test)
|
||
|
|
self.stream.write(f"{GREEN}OK{RESET}\n")
|
||
|
|
|
||
|
|
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
# Farbiger TestRunner
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
|
||
|
|
class ColoredTestRunner(unittest.TextTestRunner):
|
||
|
|
|
||
|
|
def _makeResult(self):
|
||
|
|
result = ColoredTestResult(
|
||
|
|
self.stream,
|
||
|
|
self.descriptions,
|
||
|
|
self.verbosity,
|
||
|
|
)
|
||
|
|
|
||
|
|
original_start_test = result.startTest
|
||
|
|
|
||
|
|
def patched_start_test(test):
|
||
|
|
if 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
|
||
|
|
# ---------------------------------------------------------
|
||
|
|
|
||
|
|
def main():
|
||
|
|
print("\n" + "=" * 70)
|
||
|
|
print(
|
||
|
|
f"{CYAN}Testlauf gestartet am: "
|
||
|
|
f"{datetime.datetime.now():%Y-%m-%d %H:%M:%S}{RESET}"
|
||
|
|
)
|
||
|
|
print("=" * 70 + "\n")
|
||
|
|
|
||
|
|
loader = unittest.TestLoader()
|
||
|
|
|
||
|
|
TEST_ROOT = SN_PLAN41_ROOT / "tests"
|
||
|
|
|
||
|
|
suite = loader.discover(
|
||
|
|
start_dir=str(TEST_ROOT),
|
||
|
|
pattern="test_*.py",
|
||
|
|
top_level_dir=str(SN_PLAN41_ROOT.parent),
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
runner = ColoredTestRunner(verbosity=2)
|
||
|
|
result = runner.run(suite)
|
||
|
|
|
||
|
|
return 0 if result.wasSuccessful() else 1
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
raise SystemExit(main())
|