"""pytest 共享fixtures 与约定入口(可按 backend-testing-strategy 逐步扩展)。""" from __future__ import annotations pytest_plugins = ["tests.support.auth_async_sqlite"] import os import pytest # TOML SSOT:OTEL_ENABLED env 已无效;在 pytest 最早阶段关闭 deploy.otel_enabled。 os.environ.setdefault("APP_ENV", "development") def pytest_configure(config: pytest.Config) -> None: from app.core.app_config import get_app_config get_app_config().deploy.otel_enabled = False import uuid from datetime import datetime, timezone from typing import Callable from fastapi import FastAPI from app.features.user.models import User def pytest_sessionfinish(session: pytest.Session, exitstatus: int) -> None: from app.core.telemetry import shutdown_telemetry shutdown_telemetry() def install_test_error_handlers(app: FastAPI) -> FastAPI: """为最小测试 FastAPI 应用挂载与生产一致的异常处理。""" from app.core.errors import register_exception_handlers from app.core.middleware import RequestIdMiddleware app.add_middleware(RequestIdMiddleware) register_exception_handlers(app) return app @pytest.fixture def unique_phone() -> str: """避免与测试库中已存在手机号冲突(11 位)。""" return f"138{uuid.uuid4().int % 100_000_000:08d}" @pytest.fixture def make_test_user(unique_phone: str) -> Callable[..., User]: """工厂:构造仅用于响应序列化的 User 行(未入库)。""" def _make( *, user_id: str | None = None, phone: str | None = None, nickname: str = "测试用户", ) -> User: return User( id=user_id or str(uuid.uuid4()), phone=phone or unique_phone, password_hash="x", nickname=nickname, subscription_type="free", created_at=datetime.now(timezone.utc), ) return _make