test: 按模块重写测试代码,删除旧平铺结构

按"测试规则"重写 tests/:一个模块一个目录、用例按数据→过程→验证三段书写、
不保留全局 conftest.py、测试过程只调用真实生产代码。

结构(73 个文件、30 个模块目录、477 用例):
- tests/nodes/  15 个模块目录(srt/whisper/ass/ffmpeg/frame_extract/vlm/
  subtitle_ocr/llm/llm_filter/subtitle_cleanup/subtitle_correction/
  proper_nouns/adaptive_pool/vad_profiler/echo);
- tests/app/    11 个模块目录(db/scheduler/batch/maintenance/registry/seed/
  storage/config/logging/main/routers 三组 API);
- tests/sdk/test_models、tests/web/test_crop、tests/shared(公共设施)。

测试数据随模块目录入库(tests/**/data/),删除根级 testdata/;.gitignore
的 data/ 改为 /data/,否则会连带忽略 tests/**/data/ 导致测试数据无法入库。

顺带发现并修复三个真实缺陷:
- nodes/srt.py:相邻条目缺少空行时把下一条时间轴吞进正文(静默错位),
  改为正文行遇时间戳行即报错;
- src/wov_app/scheduler.py:_file_size 只捕获 OSError,含 \x00 的产物 URI
  抛 ValueError 导致任务误判失败,改为同时捕获;
- nodes/subtitle_correction.py:生产代码依赖测试包解析 SRT,
  改用生产模块 nodes/srt.py。

真实模型/服务集成测试按外部状态跳过:新增 tests/shared/gpu_memory.py
(运行时探测显存、CUDA OOM 转跳过)与 tests/shared/llm_service.py
(无 Key / 余额 / 限流转跳过)。全量 477 passed。
This commit is contained in:
2026-09-13 15:40:56 +08:00
parent 966f3e6b4b
commit 8a715a8064
139 changed files with 20810 additions and 10733 deletions
+61
View File
@@ -0,0 +1,61 @@
"""环境与临时目录隔离(供需要 `wov_app.config` 路径常量的模块测试使用)。
规则要求测试可独立运行、不依赖全局 conftest,数据与产物目录就是测试代码
所在目录:本模块把"创建独立数据目录并把应用指向它"封装成显式调用的函数,
由各模块测试在自己的 fixture 里调用。
失败模式说明:`wov_app.config` 在**导入时**读取环境变量并锁定路径常量
DATA_DIR / DB_PATH / STORAGE_DIR)。因此隔离必须在**首次导入** config
之前完成:
- 模块级导入的测试文件(如 `from wov_app.config import STORAGE_DIR`)应在
文件顶部用 `configure_environment()`(不带 tmp_path 的进程级隔离)设置;
- 测试函数内才导入 `wov_app` 的文件,可用 `isolated_data_dir(tmp_path)`
在导入前覆盖到每个用例自己的临时目录。
"""
from __future__ import annotations
import os
import shutil
import tempfile
from pathlib import Path
# 进程级临时根目录(进程退出即清理),供 `configure_environment()` 使用。
_PROCESS_ROOT: Path | None = None
def process_data_root() -> Path:
"""返回(必要时创建)进程级测试数据根目录。
与全局 conftest 的区别:这里不使用 pytest 的 autouse fixture,也不在
导入时自动改环境变量;模块测试显式调用后才生效,因此单个模块目录
可以脱离其他测试独立运行。
"""
global _PROCESS_ROOT
if _PROCESS_ROOT is None:
_PROCESS_ROOT = Path(tempfile.mkdtemp(prefix="vrsub-test-"))
return _PROCESS_ROOT
def configure_environment(data_root: Path | None = None) -> Path:
"""把应用的数据目录、数据库、存储与后台服务指向独立测试目录。
必须在导入 `wov_app.config`(或任何会导入它的模块)之前调用,
否则路径常量已按默认值锁定。返回实际使用的数据根目录。
"""
root = data_root or process_data_root()
os.environ["WOV_DATA_DIR"] = str(root / "data")
os.environ["WOV_DB_PATH"] = str(root / "data" / "wov.db")
os.environ["WOV_STORAGE_DIR"] = str(root / "storage")
# 默认关闭自动种子与后台线程:测试显式控制执行时机,避免与断言竞态。
os.environ["WOV_AUTO_SEED"] = "0"
os.environ["WOV_SCHEDULER_ENABLED"] = "0"
os.environ["WOV_CLEANUP_ENABLED"] = "0"
os.environ["WOV_BATCH_ENABLED"] = "0"
return root
def cleanup_data_root(root: Path) -> None:
"""清理测试数据根目录(忽略错误,进程退出或 fixture 收尾时调用)。"""
shutil.rmtree(root, ignore_errors=True)