This commit is contained in:
2026-09-19 19:45:43 +08:00
parent 7183cb45f8
commit 8131b158b4
60 changed files with 7669 additions and 909 deletions

47
labs/run_tests.py Normal file
View File

@@ -0,0 +1,47 @@
"""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:]))