forked from Dan4ick/Lidar_Muxa
- tools/make_benchmark.py: аугментации спавна d_start ∈ [40, 200] м, боковой дрейф v_lat, шум продольной координаты δs (устранение инверсии s_std), сценарии стоянки; - flyguard/lobula.py: зонный пол h_lo_core = 0.16 м в межрельсовой колее, динамическое расширение габарита в кривых W_eff(d) по Corridor.sigma(d), отсечение плоскости настила платформы; - flyguard/central_complex.py: поддержка лежащих препятствий в колее без штрафа за вытянутость формы; - flyguard/synth.py: добавлен класс «человек_лежа» (1.8×0.5×0.3 м); - flyguard/descending.py: дальний мягкий канал предупреждения на дистанциях >90 м; - flyguard/export.py: экспорт детекций в 3D BBox, уровни угрозы, маркеры RViz MarkerArray; - tests/test_pipeline.py, tests/run_tests.py: юнит-тесты и автономный раннер.
83 lines
2.2 KiB
Python
83 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Автономный запуск тестов без внешних зависимостей (включая pytest)."""
|
|
import inspect
|
|
import math
|
|
import sys
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
|
|
class PytestMock:
|
|
class raises:
|
|
def __init__(self, exc_type, match=None):
|
|
self.exc_type = exc_type
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
if exc_type is None:
|
|
raise AssertionError(f"Expected {self.exc_type} but nothing was raised")
|
|
return issubclass(exc_type, self.exc_type)
|
|
|
|
@staticmethod
|
|
def approx(expected, rel=1e-6, abs=1e-6):
|
|
class Approx:
|
|
def __eq__(self, other):
|
|
return math.isclose(other, expected, rel_tol=rel, abs_tol=abs)
|
|
|
|
def __repr__(self):
|
|
return f"approx({expected})"
|
|
|
|
return Approx()
|
|
|
|
class mark:
|
|
@staticmethod
|
|
def skipif(cond, reason=""):
|
|
def dec(f):
|
|
f.__skip__ = cond
|
|
return f
|
|
|
|
return dec
|
|
|
|
|
|
sys.modules.setdefault("pytest", PytestMock())
|
|
|
|
import tests.test_pipeline as tp
|
|
|
|
|
|
def main():
|
|
passed = failed = skipped = 0
|
|
test_names = sorted([n for n in dir(tp) if n.startswith("test_")])
|
|
for name in test_names:
|
|
fn = getattr(tp, name)
|
|
if getattr(fn, "__skip__", False):
|
|
print(f"SKIP {name}")
|
|
skipped += 1
|
|
continue
|
|
try:
|
|
sig = inspect.signature(fn)
|
|
kwargs = {}
|
|
if "tmp_path" in sig.parameters:
|
|
with tempfile.TemporaryDirectory() as td:
|
|
kwargs["tmp_path"] = Path(td)
|
|
fn(**kwargs)
|
|
else:
|
|
fn()
|
|
print(f"PASS {name}")
|
|
passed += 1
|
|
except Exception as e:
|
|
print(f"FAIL {name}: {e}")
|
|
failed += 1
|
|
|
|
print(f"\nИтог: {passed} passed, {failed} failed, {skipped} skipped")
|
|
if failed > 0:
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|