# 真实数据复现测试框架 本目录是"用**真实数据**复现问题并验证修复"的集成测试框架,**不 mock 任何 模型/音频/LLM**。测试只读取你按约定放好的真实数据文件;数据缺失时整体跳过, 不影响 100% 覆盖率门禁(`pytest --cov-fail-under=100`)。 ## 你要做什么 把真实数据放到 `vrsub/testdata/` 下的两个子目录即可,测试自动发现并执行。 不需要改任何测试代码。 ### 1)时间对齐(复现"字幕时间与说话时间不吻合") ``` vrsub/testdata/alignment/ ├── .mp4|wav|... # 真实视频/音频素材(有说话内容) └── .reference.srt # 人工校对时间轴的参考字幕(说话真实发生的时间) ``` - 参考字幕用**标准 SRT**(序号/时间轴/文本/空行),时间戳格式 `HH:MM:SS,mmm -> HH:MM:SS,mmm`。 - 测试会对同一素材用生产 whisper 节点分别以 `vad_filter=True`(当前生产配置) 与 `vad_filter=False` 转写,各自与参考字幕做**最近邻时间对齐**,输出: - `平均绝对偏差`(整体同步精度) - `偏差中位数`(系统性偏早/偏晚方向与幅度) - `偏早/偏晚累计`(问题严重程度) - 复现判定:平均绝对偏差 > 0.5s,或中位偏差超出 ±0.7s,即判"过早/过晚"被 稳定捕获(红);修复后回落到容差内(绿)。 - 建议先放一段**约 30s~2min、说话清晰、有参考时间轴**的素材做第一轮复现。 ### 2)幻觉词 / 专有名词提示词规则(复现"谢谢观看/晚安"与"芒果") ``` vrsub/testdata/prompt_rules/ ├── .ja.srt # 真实视频的日文 ASR 输出字幕(标准 SRT) └── .expected.txt # 期望清单(每行一个关键词) ``` - `.ja.srt`:真实 ASR 输出,最好**包含**"谢谢观看 / 晚安 / 感谢收看" 等收尾寒暄,以及"マンゴー(芒果)"等专名。 - `.expected.txt`:目前测试内置了寒暄词表与专名名单,期望文件内容可先 为空或写备注;断言规则已内置在 `tests/realdata_contract.py` 的 `HALLUCINATION_TOKENS` / `PROPER_NOUNS_NO_TRANSLATE` 中,需要扩充时改那里 并同步更新 `.expected.txt`。 - 该测试调用**真实 LLM API**(读取 `.env` 的 `LLM_API_BASE` / `LLM_API_KEY` / `LLM_MODEL`,与生产 llm-translate 同一接口)。未配置 Key 时跳过;配置后 每次运行都会真实调用并断言"合入提示词规则后不再输出寒暄、专名不被直译"。 ## 运行 ```bash # 只跑这两类真实数据集成测试 uv run pytest tests/test_integration_alignment.py tests/test_integration_prompt_rules.py -v # 跑全部(含覆盖率门禁) uv run pytest ``` 测试发现数据后自动成为回归门禁:**修复前红、修复后绿**,防止问题回潮。 ## 文件说明 | 文件 | 作用 | | --- | --- | | `tests/realdata_contract.py` | 数据契约:目录/素材发现、SRT 解析、时间对齐指标、幻觉词/专名判定、提示词规则拼接(纯函数) | | `tests/test_integration_alignment.py` | 时间对齐集成测试(真实 whisper 节点 + 参考字幕,vad 开/关对照) | | `tests/test_integration_prompt_rules.py` | 提示词规则集成测试(真实 LLM API + 动态规则,不 mock) | ## 后续修复落点(供实现对账) 1. **时间对齐**:`nodes/whisper.py` 的 VAD / 分块偏移 / word_timestamps 策略。 测试用统一指标量化,修一处跑一次即可看到偏差回落。 2. **提示词规则**:`nodes/llm.py` 的 `translate_lines` 按 `build_translation_system_prompt` 的契约动态拼接规则(检测关键词 → 注入 对应规则),生产 `llm-translate` 走同一套 prompt。