"""labs 的统一入口:把 ``py-client`` 挂上 ``sys.path`` 后运行 labs/tests 下的全部单测。 为什么需要它:测试模块内部有 ``from tests.zt_harness import ...`` 这类导入, 所以 ``labs`` 必须作为顶层包被导入,同时 ``py-client`` 必须在 ``sys.path`` 上 (``config`` / ``libs`` / ``sdk`` / ``strategy`` 都在那里)。单独用 ``python -m unittest discover`` 很难同时满足这两点,因此统一走这个脚本。 用法(在仓库任意位置执行): py -3.14 -B labs/run_tests.py # 跑全部 py -3.14 -B labs/run_tests.py -v # 详细 py -3.14 -B labs/run_tests.py test_etf_signal # 只跑某个模块 """ import sys import unittest from pathlib import Path LABS = Path(__file__).resolve().parent REPO = LABS.parent PY_CLIENT = REPO / "py-client" for path in (str(PY_CLIENT), str(REPO)): if path not in sys.path: sys.path.insert(0, path) def build_suite(pattern: str, names: list[str]) -> unittest.TestSuite: loader = unittest.TestLoader() if names: return loader.loadTestsFromNames(names) start = LABS / "tests" # top_level_dir 指向 labs:这样导入名是 tests.xxx,测试模块里的 # "from tests.zt_harness import ..." 才能解析。 return loader.discover(str(start), pattern=pattern, top_level_dir=str(LABS)) def main(argv: list[str]) -> int: args = [a for a in argv if not a.startswith("-")] verbosity = 2 if any(a in ("-v", "--verbose") for a in argv) else 1 names = [a if "." in a else f"tests.{a}" for a in args] suite = build_suite("test_*.py", names) result = unittest.TextTestRunner(verbosity=verbosity).run(suite) return 0 if result.wasSuccessful() else 1 if __name__ == "__main__": raise SystemExit(main(sys.argv[1:]))