fix(test): 修复 batch_download session 测试全量跑时 flaky 失败 #1409
Reference in New Issue
Block a user
Delete Branch "fix/batch-download-session-flaky-v2"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
问题
PR #1406 修复了
test_batch_download_session_closed和test_batch_download_closes_session_on_error的 flaky 行为,使用patch.object(_db_mod, "SessionLocal", ...)替代字符串路径 patch。但在 develop push 的全量测试中(Run #32255),这两个测试仍然失败:
增量模式(只跑改动的测试文件)通过,全量模式失败 — 说明前序测试影响了
SessionLocal的 mock 效果。根因分析
batch_download_videos函数内部做from worker_app.db import SessionLocal。patch.object替换了模块属性,但在全量跑时,前序测试可能通过不同路径导入模块(如apps.worker.worker_app.dbvsworker_app.db),导致sys.modules中的模块引用不一致。修复
SessionLocal:_db_mod、sys.modules["worker_app.db"]、函数__globals__(如果存在)raw_fn而非通过_call_task间接调用mock_session_factory.called,帮助定位是 mock 未生效还是 session 未关闭验证
🚀 预览环境已部署
【阻塞级判定】
📊 审查概览
🔴 阻塞级问题(必须修复)
[tests/unit/test_batch_download.py: 282-284] 严重破坏测试隔离性,永久污染全局状态
sys.modules和模块全局变量中的SessionLocal,但在finally块中显式不进行还原(pass)。这导致测试运行后,Mock 对象永久残留在 Python 解释器的全局模块缓存中。后续运行的测试将直接使用这个 Mock 对象,而不是它们预期的配置,导致测试结果不可信,极易引发“测试在单独运行时通过,但在全量运行时失败”的问题,严重破坏 CI/CD 的稳定性。finally块中恢复原始的SessionLocal对象。或者,更推荐的做法是使用unittest.mock.patch上下文管理器或pytest的monkeypatchfixture,它们会自动处理清理工作,避免手动管理全局状态带来的风险。[tests/unit/test_batch_download.py: 299] 绕过任务包装器调用,可能导致测试场景失真
_call_task(batch_download_videos, ...)修改为直接调用raw_fn(...)。通常_call_task封装了 Celery 任务的上下文初始化(如current_task)、请求 ID 绑定或特定的异常处理逻辑。直接调用原始函数破坏了这一层封装,可能导致测试无法正确模拟真实的异步任务执行环境,从而遗漏上下文相关的 Bug(例如依赖current_task的逻辑将无法被测试覆盖)。_call_task调用方式,或者确保raw_fn的调用方式能完整复现任务执行时的上下文环境。如果为了解决导入缓存问题必须绕过,应证明_call_task在此场景下是多余的且不影响测试有效性。💡 改进建议(不阻塞合并)
sys.modules和__globals__是一种极其脆弱的做法(Fragile Test),容易随着代码重构或导入顺序的变化而失效。建议使用pytest的monkeypatch或unittest.mock.patch,或者通过importlib.reload在测试 setup 阶段解决导入缓存问题,而不是暴力修改全局状态。✅ 良好实践
PromiseProxy缓存难点进行了深入的尝试和修复,表明开发者关注到了测试隔离中的复杂问题。✅ 格式检查通过 | ❌ 逻辑审查需修改 | ✅ 性能无明显问题
🤖 由 AI 代码审查机器人自动生成 | 2026-08-17 12:59:52 | 模型:
CI全绿,自动审批通过。
CI全绿,自动审批通过。
🗑️ 预览环境已清理
PR #1409 已关闭或合并,对应的预览环境已被清理。