"""测试用 fixtures。 测试 DB 用临时文件 SQLite。 - 不用 in-memory:in-memory 默认 per-connection,跨连接看不到表。 - 用临时文件保证 SessionLocal 每次新连都看到同一份 schema。 顺序:set env(必须在 import app.* 之前) → import app → 建表 → TestClient """ from __future__ import annotations import os import tempfile from collections.abc import Iterator # 临时 db 文件路径,进程退出后清理 _tmp_db = tempfile.NamedTemporaryFile(suffix=".db", delete=False) _tmp_db.close() os.environ["DATABASE_URL"] = f"sqlite:///{_tmp_db.name}" os.environ.setdefault("JWT_SECRET_KEY", "test-secret-please-ignore-this-is-only-for-pytest-not-real") os.environ.setdefault("ADMIN_JWT_SECRET", "test-admin-secret-please-ignore-only-for-pytest-not-real") os.environ.setdefault("JG_APP_KEY", "test-key") os.environ.setdefault("JG_MASTER_SECRET", "test-secret") os.environ.setdefault("SMS_MOCK", "true") os.environ.setdefault("APP_ENV", "dev") os.environ.setdefault("APP_DEBUG", "false") # 测试不打 SQL 日志 # 微信支付:填 dummy 让 wxpay_configured 为真(测试里 wxpay 的网络调用全 monkeypatch,不会真发) os.environ.setdefault("WECHAT_APP_ID", "wxtest0000000000") os.environ.setdefault("WECHAT_APP_SECRET", "test-secret") os.environ.setdefault("WXPAY_MCH_ID", "test-mch") os.environ.setdefault("WXPAY_MCH_SERIAL_NO", "test-serial") os.environ.setdefault("WXPAY_PUBLIC_KEY_ID", "test-pubkey-id") os.environ.setdefault("RATE_LIMIT_ENABLED", "false") # 限流内存计数会跨用例累加,测试关掉 # 穿山甲发奖回调:测试里开启 + 给个 mock 验签密钥,test 内自签自验闭环 os.environ.setdefault("PANGLE_CALLBACK_ENABLED", "true") os.environ.setdefault("PANGLE_REWARD_SECRET", "test-pangle-secret-only-for-pytest") import pytest from fastapi.testclient import TestClient from app.db.base import Base from app.db.session import engine from app.main import app @pytest.fixture(scope="session", autouse=True) def _setup_db() -> Iterator[None]: Base.metadata.create_all(engine) yield Base.metadata.drop_all(engine) try: os.unlink(_tmp_db.name) except OSError: pass @pytest.fixture() def client() -> TestClient: return TestClient(app)