pytest测试FastAPI+Tortoise项目多测试用例触发relation不存在错误
问题原因
你遇到的报错本质是测试运行过程中,Tortoise-ORM的建表逻辑仅在首个测试执行时生效,后续测试发起数据库请求时表已被销毁,核心触发点有两个:
- 你使用的
register_tortoise方法依赖FastAPI的生命周期事件完成建表,首个测试结束后Tortoise会隐式关闭当前数据库连接,第二个测试发起请求时会重新建立连接,但此时不会重新触发建表逻辑,导致表不存在。 - 你当前的fixture没有配置显式的Tortoise连接重置、表结构重建逻辑,测试之间的数据库状态互相影响。
如果你使用的是内存型SQLite作为测试数据库,还会额外触发连接关闭即表数据全量销毁的问题,进一步加剧该报错。
解决方法
修改test_app_with_db fixture,添加显式的初始化、清理逻辑,示例修改后的代码如下:
import os import pytest from starlette.testclient import TestClient from tortoise import Tortoise, run_async from app.main import create_applications from app.config import get_settings, Settings from tortoise.contrib.fastapi import register_tortoise DATABASE_TEST_URL = os.environ.get("DATABASE_TEST_URL") def get_settings_override() -> Settings: return Settings(testing=1, database_url=DATABASE_TEST_URL) @pytest.fixture(scope="module") def test_app_with_db(): # 初始化应用配置 app = create_applications() app.dependency_overrides[get_settings] = get_settings_override # 显式同步执行Tortoise初始化、建表 async def init_db(): await Tortoise.init( db_url=DATABASE_TEST_URL, modules={"models": ["app.models.tortoise"]} ) await Tortoise.generate_schemas() run_async(init_db()) register_tortoise( app, db_url=DATABASE_TEST_URL, modules={"models": ["app.models.tortoise"]}, generate_schemas=True, add_exception_handlers=True, ) with TestClient(app) as test_client: yield test_client # 测试结束后显式清理资源 async def teardown_db(): await Tortoise._drop_databases() await Tortoise.close_connections() run_async(teardown_db())
如果你的测试数据库是持久化存储(如PostgreSQL、文件型SQLite),还可以调整fixture的scope为function,保证每个测试执行前都重建表结构,避免测试之间的数据干扰。
内容的提问来源于stack exchange,提问作者GuruYaya
相关产品推荐
相关产品推荐

