首页 文章

Flask SQLAlchemy pytest - 不回滚我的会话

提问于
浏览
1

关于堆栈溢出有几个类似的问题,如果我通过询问另一个礼节打破礼仪,我会提前道歉,但我似乎无法想出适当的咒语来使这项工作 .

我正在尝试使用Flask Flask-SQLAlchemy然后使用pytest来管理会话,这样当功能范围的pytest fixture被拆除时,当前的转换将被回滚 .

其他一些问题似乎主张在函数范围使用db“drop all和create all”pytest fixture,但我正在尝试使用join session,并使用rollbacks,因为我有很多测试 . 这会大大加快速度 .

http://alexmic.net/flask-sqlalchemy-pytest/是我找到原始想法的地方,而Isolating py.test DB sessions in Flask-SQLAlchemy是推荐使用功能级别db重新创建的问题之一 .

我也见过https://github.com/mitsuhiko/flask-sqlalchemy/pull/249,但似乎已经发布了flask-sqlalchemy 2.1(我正在使用) .

我现在的(非常小的,希望可以立即理解的)回购在这里:https://github.com/hoopes/flask-pytest-example

有两个打印语句 - 第一个(在示例/ __ init__.py中)应该有一个Account对象,第二个(在test / conftest.py中)是我希望在事务回滚后清除db的地方 .

如果您从测试目录运行 pip install -r requirements.txt ,则应该看到两个print语句 .

我在绳子的尽头 - 必须有一些我想念的东西,但对于我的生活,我似乎无法找到它 .

帮助我,所以,你是我唯一的希望!

2 回答

  • 2

    我也遇到了回滚问题,我的代码可以找到here

    阅读完一些文档后,似乎应该在会话中调用 begin() 函数 .

    所以在你的情况下,我会将会话夹具更新为:

    @pytest.yield_fixture(scope='function', autouse=True)
    def session(db, request):
        """Creates a new database session for a test."""
    
        db.session.begin()
    
        yield db.session
    
        db.session.rollback()
        db.session.remove()
    

    我没有测试这段代码,但是当我在我的代码上尝试它时,我收到以下错误:

    INTERNALERROR> Traceback (most recent call last):
    INTERNALERROR>   File "./venv/lib/python2.7/site-packages/_pytest/main.py", line 90, in wrap_session
    INTERNALERROR>     session.exitstatus = doit(config, session) or 0
    ...
    INTERNALERROR>   File "./venv/lib/python2.7/site-packages/_pytest/python.py", line 59, in filter_traceback
    INTERNALERROR>     return entry.path != cutdir1 and not entry.path.relto(cutdir2)
    INTERNALERROR> AttributeError: 'str' object has no attribute 'relto'
    
  • 0

    您可能想尝试pytest-flask-sqlalchemy-transactions . 它是一个暴露 db_session fixture的插件,可以完成你的博客文章,并对嵌套事务提供一些额外的支持,涵盖更广泛的用户案例 . 还有一些配置选项可用于在应用程序中模拟连接,因此您也可以从代码库中运行任意方法 .

    对于 test_accounts.py ,您可以执行以下操作:

    from example import db, Account
    
    
    class TestAccounts(object):
    
        def test_update_view(self, db_session):
    
            test_acct = Account(username='abc')
    
            db_session.add(test_acct)
            db_session.commit()
    
            resp = self.client.post('/update',
                                    data={'a':1},
                                    content_type='application/json')
    
            assert resp.status_code == 200
    

    该插件需要通过 _db fixture访问您的数据库,但由于您已经在 conftest.py 中定义了 db fixture,因此您可以轻松地设置数据库访问:

    @pytest.fixture(scope='session')
    def _db(db):
        return db
    

    您可以在the docs中找到有关如何设置和安装的详细信息 . 希望这可以帮助!

相关问题