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

PyTest结合SQLAlchemy测试数据回滚失效问题求助

问题诊断

你的回滚操作无效的核心原因有两个:

  1. 测试代码里手动创建的self.session和Flask接口处理请求时用的数据库会话不是同一个实例,回滚这个session根本影响不到接口写入的数据。
  2. 手动调用setup_class和teardown_class不符合pytest的生命周期管理逻辑,会导致会话状态混乱,而且你没有为会话显式开启事务,回滚操作没有可作用的对象。
修复代码

用pytest fixture统一管理数据库会话和事务,确保接口和测试用的是同一个会话,测试结束后自动回滚:

import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
from your_app import app  # 替换成你的实际app导入路径

engine = create_engine(url)
Session = scoped_session(sessionmaker(bind=engine))

class TestApps:
    @pytest.fixture(autouse=True)
    def db_transaction(self):
        # 开启数据库连接和事务
        conn = engine.connect()
        trans = conn.begin()
        
        # 创建绑定到当前连接的会话,并替换app使用的会话
        # 这里假设你的app通过app.db_session引用数据库会话,根据实际情况修改
        test_session = Session(bind=conn)
        original_session = app.db_session
        app.db_session = test_session
        
        yield
        
        # 回滚事务、清理资源
        trans.rollback()
        conn.close()
        Session.remove()
        app.db_session = original_session

    @pytest.fixture
    def client(self):
        return app.test_client()

    @pytest.fixture
    def mock_verify(self):
        with patch("flask_jwt_extended.view_decorators.verify_jwt_in_request") as mock:
            yield mock

    @patch('flask_jwt_extended.view_decorators.verify_jwt_in_request')
    def test_create_app(self, mock_verify, client):
        mimetype = "application/json"
        headers = {"Content-Type": mimetype}
        data = {
            "app_name": "Fire Dampers",
            "short_code": "TFF",
            "icon": "icon2.png"
        }

        response = client.post('/application/create', data=json.dumps(data), headers=headers)

        assert response.status_code == 200
关键说明
  • autouse=True的fixture会自动作用于每个测试用例,无需手动调用,确保每个测试都在独立的事务中执行。
  • 显式开启数据库连接的事务,所有接口操作都会被包含在这个事务里,测试结束后直接回滚整个事务,彻底清除测试数据。
  • 将app的数据库会话替换为测试用的会话,保证接口和测试使用的是同一个会话上下文。
  • 使用scoped_session避免多线程环境下的会话冲突,适合Flask的请求上下文模型。
额外注意
  • 如果你在app中用了before_request或after_request钩子自动提交会话,需要在测试中临时禁用这些钩子,或者调整逻辑让测试期间不自动提交。
  • 确认app中数据库会话的引用方式,比如有些项目用current_app获取会话,需要对应修改fixture中的替换逻辑。

内容的提问来源于stack exchange,提问作者Graham Patrick

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 22:05:27