I've been using Flask-Testing to test my API, but I've recently run into some issues. What I'll normally want to do is verify an endpoint updates my database as expected. To do that, I'll verify a database value before hitting the end point, then hit the endpoint, and then verify the value has been updated, like so:
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
This works, but my issue is it only works if we clear out the session between calls with db.session.commit()
. That feels like it's asking for trouble, because there's a good chance one of the other programmers working on this will forget to include that at some point. On top of that, unnecessarily committing so much causes slowdown in the test. Is there any reasonable way to just force data refresh inside the query? Something like db.session.query(MyDBItem, refresh=True)
? Or some other generally less error-prone way of doing this?
I've already tried session.refresh()
and session.expire_all()
, and neither consistently works and both have the same potential pitfalls as session.commit()
It looks like setting isolation level to READ COMMITTED
might do the trick, but how to do this in flask-SQLAlchemy is unclear.