Files
create/tests/run_kindred_tests.py

104 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""Runner for Kindred Create addon tests.
Tier 1 (pure logic) tests run with the system Python — no FreeCAD binary
required. Tier 2 (FreeCAD headless) tests are skipped unless FreeCADCmd
is found on PATH.
Usage:
python3 tests/run_kindred_tests.py # Tier 1 only
python3 tests/run_kindred_tests.py --all # Tier 1 + Tier 2 (needs FreeCADCmd)
Exit codes:
0 All tests passed
1 One or more tests failed
"""
import os
import shutil
import subprocess
import sys
import unittest
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parent.parent
def run_pure_tests() -> bool:
"""Discover and run Tier 1 pure-logic tests. Returns True on success."""
loader = unittest.TestLoader()
suite = loader.discover(
start_dir=str(REPO_ROOT / "tests"),
pattern="test_kindred_pure.py",
top_level_dir=str(REPO_ROOT / "tests"),
)
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)
return result.wasSuccessful()
def run_freecad_tests() -> bool:
"""Run Tier 2 tests inside FreeCADCmd. Returns True on success."""
freecad_cmd = shutil.which("FreeCADCmd")
if not freecad_cmd:
# Check build directories
for candidate in (
REPO_ROOT / "build" / "debug" / "bin" / "FreeCADCmd",
REPO_ROOT / "build" / "release" / "bin" / "FreeCADCmd",
):
if candidate.exists():
freecad_cmd = str(candidate)
break
if not freecad_cmd:
print("\n[SKIP] FreeCADCmd not found — skipping Tier 2 tests")
return True # Not a failure, just skipped
print(f"\n{'=' * 70}")
print(f"Tier 2: FreeCAD headless tests via {freecad_cmd}")
print(f"{'=' * 70}\n")
# Tier 2 test modules registered via FreeCAD.__unit_test__
test_modules = ["TestKindredCreate"]
all_ok = True
for mod in test_modules:
print(f"--- Running {mod} ---")
proc = subprocess.run(
[freecad_cmd, "-t", mod],
cwd=str(REPO_ROOT),
timeout=120,
)
if proc.returncode != 0:
all_ok = False
return all_ok
def main():
os.chdir(REPO_ROOT)
run_all = "--all" in sys.argv
print(f"{'=' * 70}")
print("Tier 1: Pure-logic tests (no FreeCAD binary required)")
print(f"{'=' * 70}\n")
tier1_ok = run_pure_tests()
tier2_ok = True
if run_all:
tier2_ok = run_freecad_tests()
print(f"\n{'=' * 70}")
print(f" Tier 1 (pure): {'PASS' if tier1_ok else 'FAIL'}")
if run_all:
print(f" Tier 2 (FreeCAD): {'PASS' if tier2_ok else 'FAIL'}")
print(f"{'=' * 70}")
sys.exit(0 if (tier1_ok and tier2_ok) else 1)
if __name__ == "__main__":
main()