git/orchard/main
tests/run.py
65 lines2 KB last change raw · history
"""Run every test module in one go.

Each test module is independently runnable and also pytest-compatible; this
runner exists so the suite can be executed without pytest installed.
"""

from __future__ import annotations

import importlib.util
import sys
import traceback
from pathlib import Path

HERE = Path(__file__).resolve().parent


def load(path: Path):
    spec = importlib.util.spec_from_file_location(path.stem, path)
    module = importlib.util.module_from_spec(spec)
    sys.modules[path.stem] = module
    assert spec.loader is not None
    spec.loader.exec_module(module)
    return module


def main() -> int:
    total = failed = 0
    verbose = "-v" in sys.argv
    modules = sorted(p for p in HERE.glob("test_*.py"))
    for path in modules:
        try:
            module = load(path)
        except Exception:  # noqa: BLE001
            print(f"\n{path.stem}: FAILED TO IMPORT")
            traceback.print_exc()
            failed += 1
            continue
        tests = [
            (n, f) for n, f in sorted(vars(module).items()) if n.startswith("test_") and callable(f)
        ]
        module_failed = 0
        for name, fn in tests:
            total += 1
            try:
                fn()
            except Exception as exc:  # noqa: BLE001
                module_failed += 1
                print(f"FAIL  {path.stem}::{name}")
                print(f"      {type(exc).__name__}: {exc}")
                if verbose:
                    traceback.print_exc()
            else:
                if verbose:
                    print(f"ok    {path.stem}::{name}")
        failed += module_failed
        status = "ok" if not module_failed else f"{module_failed} FAILED"
        print(f"{status:>10}  {path.stem}  ({len(tests)} tests)")

    print(f"\n{total - failed}/{total} passed across {len(modules)} modules")
    return 1 if failed else 0


if __name__ == "__main__":
    raise SystemExit(main())