按"测试规则"重写 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。
128 lines
4.2 KiB
Python
128 lines
4.2 KiB
Python
"""src/wov_app/seed.py 的模块级测试(数据 → 测试过程 → 验证结果)。
|
|
|
|
被测模块:`src/wov_app/seed.py`(从 workflows/*.json 载入内置工作流,幂等),
|
|
可独立调用。用例使用真实仓库工作流 JSON 与临时 SQLite 库。
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from wov_app.db import Database
|
|
from wov_app.seed import seed_default_workflows
|
|
|
|
# 仓库根与真实内置工作流目录。
|
|
WORKSPACE = Path(__file__).resolve().parents[3]
|
|
WORKFLOWS_DIR = WORKSPACE / "workflows"
|
|
|
|
|
|
def _db(tmp_path: Path) -> Database:
|
|
"""每个用例一个临时 SQLite 库。"""
|
|
return Database(tmp_path / "wov.db")
|
|
|
|
|
|
def test_seed_loads_all_builtin_workflows(tmp_path: Path) -> None:
|
|
"""真实 workflows/*.json 全部写入库,且数量与文件数一致。"""
|
|
# 数据:仓库真实工作流数据文件。
|
|
db = _db(tmp_path)
|
|
expected = {p.stem for p in WORKFLOWS_DIR.glob("*.json")}
|
|
assert expected, "仓库应至少有一个内置工作流数据文件"
|
|
|
|
# 测试过程
|
|
created = seed_default_workflows(db, WORKFLOWS_DIR)
|
|
stored = {w["id"] for w in db.list_workflows()}
|
|
|
|
# 验证结果
|
|
assert created == len(expected)
|
|
assert stored == expected
|
|
|
|
|
|
def test_seed_creates_version_record_with_valid_dag(tmp_path: Path) -> None:
|
|
"""每个工作流写入 v1 版本记录,DAG 通过结构校验(节点/边合法)。"""
|
|
# 数据:真实工作流目录。
|
|
db = _db(tmp_path)
|
|
|
|
# 测试过程
|
|
seed_default_workflows(db, WORKFLOWS_DIR)
|
|
|
|
# 验证结果:以真实 OCR 工作流为例,节点与版本齐全。
|
|
version = db.get_latest_workflow_version("ocr-subtitle")
|
|
assert version is not None
|
|
definition = version["definition"]
|
|
node_ids = {n["id"] for n in definition["nodes"]}
|
|
assert {"extract", "ocr", "filter"} <= node_ids
|
|
assert definition["edges"]
|
|
|
|
|
|
def test_seed_is_idempotent(tmp_path: Path) -> None:
|
|
"""重复 seed 不覆盖已有工作流,第二次返回创建数 0。"""
|
|
# 数据:先 seed 一次。
|
|
db = _db(tmp_path)
|
|
first = seed_default_workflows(db, WORKFLOWS_DIR)
|
|
|
|
# 测试过程:再次 seed。
|
|
second = seed_default_workflows(db, WORKFLOWS_DIR)
|
|
|
|
# 验证结果
|
|
assert first > 0
|
|
assert second == 0
|
|
assert len(db.list_workflows()) == first
|
|
|
|
|
|
def test_seed_does_not_overwrite_user_modification(tmp_path: Path) -> None:
|
|
"""已存在的工作流不被 seed 覆盖(保护用户改过的数据)。"""
|
|
# 数据:先写入一个与内置同 ID 的自定义工作流。
|
|
db = _db(tmp_path)
|
|
db.upsert_workflow({
|
|
"id": "zh-direct", "name": "用户改过的名字", "description": "", "published": 0,
|
|
"latest_version": 1,
|
|
})
|
|
|
|
# 测试过程
|
|
seed_default_workflows(db, WORKFLOWS_DIR)
|
|
|
|
# 验证结果:用户版本保留。
|
|
assert db.get_workflow("zh-direct")["name"] == "用户改过的名字"
|
|
|
|
|
|
def test_seed_from_empty_directory_creates_nothing(tmp_path: Path) -> None:
|
|
"""空目录不创建任何工作流(数据驱动,无硬编码兜底)。"""
|
|
# 数据:空目录。
|
|
empty = tmp_path / "workflows"
|
|
empty.mkdir()
|
|
db = _db(tmp_path)
|
|
|
|
# 测试过程
|
|
created = seed_default_workflows(db, empty)
|
|
|
|
# 验证结果
|
|
assert created == 0
|
|
assert db.list_workflows() == []
|
|
|
|
|
|
def test_seed_marks_workflows_published(tmp_path: Path) -> None:
|
|
"""内置工作流默认已发布(用户端可直接选择执行)。"""
|
|
# 数据:真实工作流目录。
|
|
db = _db(tmp_path)
|
|
|
|
# 测试过程
|
|
seed_default_workflows(db, WORKFLOWS_DIR)
|
|
|
|
# 验证结果
|
|
for workflow in db.list_workflows():
|
|
assert workflow["published"] == 1
|
|
|
|
|
|
def test_seed_honors_version_from_data_file(tmp_path: Path) -> None:
|
|
"""版本号取自数据文件(不同工作流可有不同当前版本)。"""
|
|
# 数据:真实工作流目录(含 v7 的 ocr-subtitle)。
|
|
db = _db(tmp_path)
|
|
|
|
# 测试过程
|
|
seed_default_workflows(db, WORKFLOWS_DIR)
|
|
|
|
# 验证结果:与数据文件声明一致。
|
|
payload = json.loads((WORKFLOWS_DIR / "ocr-subtitle.json").read_text(encoding="utf-8"))
|
|
assert db.get_workflow("ocr-subtitle")["latest_version"] == int(payload.get("version", 1))
|