feat(scripts): 添加批量生成 YouTube Studio 内容管理器 URL 的脚本

This commit is contained in:
2026-08-21 18:21:03 +08:00
commit c1b39e9466
29 changed files with 4020 additions and 0 deletions

67
tests/conftest.py Normal file
View File

@@ -0,0 +1,67 @@
# -*- 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"
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 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,
)