Files

82 lines
2.5 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""cn-financial-scraper 测试启动包装。
用法(在技能根目录):
python runtests.py # 跑全部测试
python runtests.py tests/test_infra_suite.py # 跑指定文件
python runtests.py -k backtest # 关键字过滤
为什么需要这个包装:
Python 在 import conftest.py 时会先编译源码再执行,
因此 conftest.py 内部即使设置了 sys.dont_write_bytecode = True
也晚于自身字节码的写入,会留下 __pycache__/conftest.cpython-*.pyc。
本包装:
1. 在 Python 启动前通过 PYTHONDONTWRITEBYTECODE=1 抑制字节码写入
2. 跑测试前后自动清理已生成的 __pycache__(彻底保证交付包干净)
"""
import os
import shutil
import sys
from pathlib import Path
try:
import pytest
except ImportError: # pragma: no cover
pytest = None
def _cleanup_pycache():
"""清理项目内所有 __pycache__ 与 .pyc 文件。
这是本项目的「防上传二进制文件」关键防线:
由于 Python 字节码生成是 import 时的固行为,无法仅靠 env 变量
完全阻止(conftest.py 自身的 pyc 在加载时即生成)。
所以采用「跑完测试立刻清理」兜底方案。
"""
root = Path(__file__).resolve().parent
cleaned = 0
# 1) 删除所有 __pycache__ 目录
for cache_dir in root.rglob("__pycache__"):
try:
shutil.rmtree(cache_dir)
cleaned += 1
except OSError:
pass
# 2) 兜底删除散落的 .pyc 文件
for pyc in root.rglob("*.pyc"):
try:
pyc.unlink()
cleaned += 1
except OSError:
pass
if cleaned:
print(f"🧹 清理 {cleaned} 个字节码缓存项")
def main() -> int:
# 1) 必须在 Python 启动早期设置,子进程继承
os.environ["PYTHONDONTWRITEBYTECODE"] = "1"
sys.dont_write_bytecode = True
# 2) 跑测试前先清理(兜底之前可能残留的)
_cleanup_pycache()
# 3) 组装 pytest 参数
args = sys.argv[1:] if len(sys.argv) > 1 else ["tests/"]
if pytest is None:
print("pytest 未安装,请先安装 pytest 后运行。")
return 2
# 4) 同一进程内运行,避免 Windows 上子进程启动后 stdout flush 报 OSError
print(f"🧪 pytest {' '.join(args)}")
rc = pytest.main(args)
# 5) 跑完测试立刻清理(防御性)
_cleanup_pycache()
return rc
if __name__ == "__main__":
sys.exit(main())