1

我一直在使用 Flask-Testing 来测试我的 API,但我最近遇到了一些问题。我通常想要做的是验证端点按预期更新我的数据库。为此,我将在到达终点之前验证数据库值,然后到达终点,然后验证值是否已更新,如下所示:

def test_some_end_point(self):
    # make sure the item doesn't exist yet.
    with pytest.raises(NoResultFound):
        db.session.query(MyDBItem)\
                .filter_by(name='blah').one()
    db.session.commit()
    # now make sure it's created, the right status code is returned,
    # and it has correct data.
    path = "my/path/to/endpoint"
    post_data = {'term': 'blah', 'other_data': 'meh'}
    response = self.post_data_and_get_result(
        path, post_data)
    assert response.status_code == 204
    item = db.session.query(MyDBItem)\
        .filter_by(name='blah').one()
    assert item.usages == 1

这行得通,但我的问题是,它只有在我们清除调用之间的会话时才有效db.session.commit()。感觉就像是在自找麻烦,因为其他从事此工作的程序员很可能会在某些时候忘记包含该内容。最重要的是,不必要地提交这么多会导致测试速度变慢。是否有任何合理的方法来强制在查询中刷新数据?像db.session.query(MyDBItem, refresh=True)什么?或者其他一些通常不太容易出错的方法?

我已经尝试过session.refresh()and session.expire_all(),但两者都没有始终如一的工作,并且都具有与 session.commit() 相同的潜在陷阱

看起来将隔离级别设置为READ COMMITTED可能会解决问题,但如何在 flask-SQLAlchemy 中执行此操作尚不清楚。

4

1 回答 1

0

如果您使用的数据库支持事务,则可以db.session.flush()改用。您可以在测试设置和回滚时修补提交功能,或删除会话并在拆卸时取消修补。例如:

from flask.ext.testing import TestCase

class BaseTestCase(TestCase):
    def create_app(self):
        pass

    def setUp(self):
        self.orig_commit = db.session.commit
        db.session.commit = db.session.flush

    def tearDown(self):
        db.session.remove()
        db.session.commit = self.orig_commit
于 2015-10-26T15:26:31.293 回答