You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建pytest Fixture实现测试模块级数据库清理?FastAPI+Pony ORM

解决FastAPI+Pony ORM项目中pytest测试的数据库清理问题

核心问题分析

你之前用scope="module"的fixture没生效,大概率是这几个原因:

  • 未正确关闭数据库会话,导致清空操作被锁或未生效
  • 误用droptables(cleardata=True)(该方法是删除表结构,而非仅清空数据,后续测试可能因表不存在报错)
  • 未设置autouse=True,fixture未自动应用到所有测试模块

解决方案:自动清理的pytest全局Fixture

在test/conftest.py文件中编写全局fixture(pytest会自动加载该文件,无需在测试中手动导入),确保每个测试模块执行前后数据库都是空的。

方案1:仅清空数据(推荐,速度更快)

适合表结构固定的场景,只清空表内数据,保留表结构:

import pytest
from app.db import db  # 替换为你项目中Database对象的实际导入路径

@pytest.fixture(scope="module", autouse=True)
def clean_database_per_module():
    # 测试模块执行前:清空所有表数据
    with db.session:
        db.session.rollback()  # 回滚未提交的会话
        db.session.close()     # 关闭现有会话避免锁表
    db.truncate_all_tables()   # Pony ORM提供的批量清空数据方法
    
    yield  # 执行当前测试模块的所有用例
    
    # 测试模块执行后:再次清空数据,确保下一个模块环境干净
    db.truncate_all_tables()

方案2:重建表结构

适合测试中会修改表结构的场景,删表后重新创建:

import pytest
from app.db import db

@pytest.fixture(scope="module", autouse=True)
def reset_database_per_module():
    # 测试前:删除所有表并重建
    db.drop_all_tables(with_all_data=True)
    db.generate_mapping(create_tables=True)
    
    yield
    
    # 测试后:删除所有表
    db.drop_all_tables(with_all_data=True)

关键配置说明

  • scope="module":表示fixture在每个测试模块(.py文件)执行前后各运行一次
  • autouse=True:自动应用到所有测试模块,无需在测试用例中显式调用
  • 会话处理:必须先回滚+关闭会话,避免数据库锁导致清空操作失败

测试运行

直接在项目根目录执行命令即可批量运行所有测试:

pytest test/

额外注意事项

  • 必须使用测试专用数据库:绝对不能在生产/开发数据库上运行测试清理逻辑
  • 若需每个测试函数都清空数据库:将scope="module"改为scope="function"
  • 测试用例中的数据库操作:执行完后记得提交或回滚,避免会话残留数据

内容的提问来源于stack exchange,提问作者Adolfo Banchio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 17:55:29