Files
lyxy-document/run_tests.py
lanyuanxiaoyao 675235f5b3 feat: 新增测试运行器脚本 run_tests.py
- 新增根目录 run_tests.py,自动根据测试类型加载依赖
- 支持所有测试类型:pdf/docx/xlsx/pptx/html/xls/doc/ppt/cli/core/utils/all
- 支持透传 pytest 参数(-v/--cov 等)
- 补全 advice_generator.py 中的 DocReader 和 PptReader 映射
- 更新 README.md,简化测试命令说明
2026-03-16 23:14:28 +08:00

221 lines
6.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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 <test_type> [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()