#!/usr/bin/env python3 """测试运行器 - 自动根据测试类型加载依赖并运行 pytest""" import argparse import os import shutil import subprocess import sys from pathlib import Path # 确定项目根目录和脚本路径 script_file = Path(__file__).resolve() project_root = script_file.parent scripts_dir = project_root / "scripts" bootstrap_path = str(scripts_dir / "bootstrap.py") # 将 scripts/ 目录添加到 sys.path if str(scripts_dir) not in sys.path: sys.path.append(str(scripts_dir)) # 抑制第三方库日志 os.environ["HF_HUB_DISABLE_PROGRESS_BARS"] = "1" os.environ["HF_HUB_DISABLE_TELEMETRY"] = "1" os.environ["TQDM_DISABLE"] = "1" # 测试类型映射 _TEST_TYPES = { # 文件类型测试(有依赖配置) "pdf": {"key": "pdf", "path": "tests/test_readers/test_pdf/"}, "docx": {"key": "docx", "path": "tests/test_readers/test_docx/"}, "xlsx": {"key": "xlsx", "path": "tests/test_readers/test_xlsx/"}, "pptx": {"key": "pptx", "path": "tests/test_readers/test_pptx/"}, "html": {"key": "html", "path": "tests/test_readers/test_html/"}, "xls": {"key": "xls", "path": "tests/test_readers/test_xls/"}, "doc": {"key": "doc", "path": "tests/test_readers/test_doc/"}, "ppt": {"key": "ppt", "path": "tests/test_readers/test_ppt/"}, # 核心测试(无特殊依赖) "cli": {"key": None, "path": "tests/test_cli/"}, "core": {"key": None, "path": "tests/test_core/"}, "utils": {"key": None, "path": "tests/test_utils/"}, # 所有测试(合并所有依赖) "all": {"key": "all", "path": "tests/"}, } def get_dependencies_for_type(test_type: str, platform_id: str): """ 获取指定测试类型的依赖配置。 Args: test_type: 测试类型(pdf/docx/.../all) platform_id: 平台标识 Returns: (python_version, dependencies) 元组 """ from config import DEPENDENCIES config = _TEST_TYPES.get(test_type) if not config: return None, [] key = config["key"] if key is None: # 无特殊依赖的测试类型(cli/core/utils) return None, [] if key == "all": # 收集所有类型的依赖并去重 python_version = None all_deps = set() for type_key, type_config in DEPENDENCIES.items(): # 先尝试特定平台配置 if platform_id in type_config: cfg = type_config[platform_id] elif "default" in type_config: cfg = type_config["default"] else: continue # 记录 python 版本(优先使用有特殊要求的) if cfg.get("python"): python_version = cfg["python"] # 收集依赖 for dep in cfg.get("dependencies", []): all_deps.add(dep) return python_version, list(all_deps) # 单个类型的依赖 if key not in DEPENDENCIES: return None, [] type_config = DEPENDENCIES[key] if platform_id in type_config: cfg = type_config[platform_id] elif "default" in type_config: cfg = type_config["default"] else: return None, [] return cfg.get("python"), cfg.get("dependencies", []) def generate_uv_args( dependencies: list, test_path: str, pytest_args: list, python_version: str = None, ): """ 生成 uv run 命令参数列表(用于 subprocess.run)。 Args: dependencies: 依赖包列表 test_path: 测试路径 pytest_args: 透传给 pytest 的参数 python_version: 需要的 python 版本,None 表示不指定 Returns: uv run 命令参数列表 """ args = ["uv", "run"] if python_version: args.extend(["--python", python_version]) # 添加 pytest args.extend(["--with", "pytest"]) # 添加其他依赖 for dep in dependencies: args.extend(["--with", dep]) # 添加 pytest 命令 args.append("pytest") # 添加测试路径 args.append(test_path) # 添加透传的 pytest 参数 args.extend(pytest_args) return args def main(): """主函数:解析参数并运行测试""" # 解析命令行参数 parser = argparse.ArgumentParser( description="自动根据测试类型加载依赖并运行 pytest", usage="%(prog)s [pytest_args...]", ) parser.add_argument( "test_type", choices=list(_TEST_TYPES.keys()), help="测试类型: " + ", ".join(_TEST_TYPES.keys()), ) parser.add_argument( "pytest_args", nargs=argparse.REMAINDER, help="透传给 pytest 的参数(如 -v, --cov 等)", ) # 如果没有参数,显示帮助 if len(sys.argv) == 1: parser.print_help() sys.exit(1) # 特殊处理:如果第一个参数是帮助选项 if sys.argv[1] in ("-h", "--help"): parser.print_help() sys.exit(0) # 使用 parse_known_args 来正确处理透传参数 # 因为 argparse.REMAINDER 会吃掉 --help,我们手动处理 test_type = sys.argv[1] pytest_args = sys.argv[2:] # 验证 test_type if test_type not in _TEST_TYPES: print(f"错误: 未知的测试类型 '{test_type}'") print(f"可用类型: {', '.join(_TEST_TYPES.keys())}") sys.exit(1) # 检测 uv 是否可用 uv_path = shutil.which("uv") if not uv_path: print("错误: 未找到 uv,请先安装 uv") sys.exit(1) # 获取测试配置 test_config = _TEST_TYPES[test_type] test_path = test_config["path"] # 导入需要的模块 from core.advice_generator import get_platform # 获取平台和依赖配置 platform_id = get_platform() python_version, dependencies = get_dependencies_for_type(test_type, platform_id) # 生成 uv 命令参数 uv_args = generate_uv_args( dependencies=dependencies, test_path=test_path, pytest_args=pytest_args, python_version=python_version, ) # 设置环境变量 env = os.environ.copy() env["PYTHONPATH"] = str(project_root) # 执行测试 result = subprocess.run(uv_args, env=env, cwd=str(project_root)) sys.exit(result.returncode) if __name__ == "__main__": main()