75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""测试公共设施:把两个 skill 目录下的独立脚本按路径加载为模块,供单元测试直接 import。
|
||
|
||
两个被测脚本均为独立脚本(非 Python 包),用 importlib 按文件路径加载:
|
||
- skills/yt-studio-url-builder/scripts/build_studio_urls.py
|
||
- skills/youtube-studio-csv-download/scripts/youtube_export_download.py
|
||
|
||
CLI 端到端测试则通过 subprocess 以 sys.executable 运行脚本(见 test_*_cli.py)。
|
||
"""
|
||
|
||
import importlib.util
|
||
import os
|
||
import subprocess
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
import pytest
|
||
|
||
ROOT = Path(__file__).resolve().parent.parent
|
||
|
||
URL_BUILDER_SCRIPT = ROOT / "skills" / "yt-studio-url-builder" / "scripts" / "build_studio_urls.py"
|
||
COUNTRIES_JSON = URL_BUILDER_SCRIPT.parent / "countries.json"
|
||
DOWNLOADER_SCRIPT = ROOT / "skills" / "youtube-studio-csv-download" / "scripts" / "youtube_export_download.py"
|
||
LOOKUP_SCRIPT = ROOT / "scripts" / "lookup_groups.py"
|
||
|
||
|
||
def _load_module(name, path):
|
||
"""按文件路径加载独立脚本为 Python 模块。"""
|
||
spec = importlib.util.spec_from_file_location(name, path)
|
||
assert spec is not None and spec.loader is not None
|
||
mod = importlib.util.module_from_spec(spec)
|
||
spec.loader.exec_module(mod)
|
||
return mod
|
||
|
||
|
||
@pytest.fixture(scope="session")
|
||
def url_builder():
|
||
"""build_studio_urls.py 模块(会话级,加载一次)。"""
|
||
return _load_module("build_studio_urls_under_test", URL_BUILDER_SCRIPT)
|
||
|
||
|
||
@pytest.fixture(scope="session")
|
||
def downloader():
|
||
"""youtube_export_download.py 模块(会话级,加载一次)。"""
|
||
return _load_module("youtube_export_download_under_test", DOWNLOADER_SCRIPT)
|
||
|
||
|
||
@pytest.fixture(scope="session")
|
||
def lookup_groups():
|
||
"""lookup_groups.py 模块(会话级,加载一次)。"""
|
||
return _load_module("lookup_groups_under_test", LOOKUP_SCRIPT)
|
||
|
||
|
||
@pytest.fixture(scope="session")
|
||
def real_countries(url_builder):
|
||
"""脚本自带 countries.json 加载出的国家映射。"""
|
||
return url_builder.load_country_map(str(COUNTRIES_JSON))
|
||
|
||
|
||
def run_script(script, args, cwd=None):
|
||
"""以子进程运行被测脚本(uv run pytest 下 sys.executable 即 venv python)。
|
||
|
||
强制子进程 PYTHONUTF8=1,避免 Windows 管道输出按 GBK 解码导致中文乱码。
|
||
"""
|
||
env = {**os.environ, "PYTHONUTF8": "1", "PYTHONIOENCODING": "utf-8"}
|
||
return subprocess.run(
|
||
[sys.executable, str(script), *args],
|
||
capture_output=True,
|
||
text=True,
|
||
encoding="utf-8",
|
||
errors="replace",
|
||
cwd=cwd,
|
||
env=env,
|
||
)
|