conftest.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. """Root-level conftest to patch ctranslate2 before tests import app.main."""
  2. import sys
  3. class _MockModels:
  4. class WhisperGenerationResult:
  5. pass
  6. class _MockCTranslate2:
  7. StorageView = type("StorageView", (), {})
  8. models = _MockModels()
  9. # Install mock before any real import of ctranslate2
  10. if "ctranslate2" not in sys.modules:
  11. sys.modules["ctranslate2"] = _MockCTranslate2()
  12. import pytest_asyncio # noqa: E402
  13. @pytest_asyncio.fixture
  14. async def init_checkpointer():
  15. """为测试初始化 LangGraph checkpointer(等价于 app startup 中的 init_checkpointer())。
  16. pytest(httpx ASGITransport)不触发 FastAPI startup,导致依赖
  17. get_checkpointer() 的图(chat/health_coach)抛 "checkpointer 未初始化"。
  18. pytest-asyncio strict 模式每个测试独立事件循环,而 chat.py 模块级缓存图在
  19. 编译期绑定 saver 单例。因此 teardown 必须:① 关闭连接并重置 saver 单例;
  20. ② 清空 chat._graph 缓存,让下一个测试在自己的 loop 内重建图,
  21. 否则跨测试复用旧 loop 的 saver 会报 "no active connection"。
  22. """
  23. import app.api.chat as chat_mod
  24. from app import checkpointer as cp
  25. await cp.init_checkpointer()
  26. yield
  27. if cp._saver is not None:
  28. closer = getattr(cp._saver, "aclose", None)
  29. if closer is not None:
  30. try:
  31. await closer()
  32. except Exception:
  33. pass
  34. conn = getattr(cp._saver, "conn", None)
  35. if conn is not None:
  36. try:
  37. await conn.close()
  38. except Exception:
  39. pass
  40. cp._saver = None
  41. chat_mod._graph = None