I'm trying to build a Flask app with Flask-SQLAlchemy; I use pytest to test the DB. One of the problems seems to be creating isolated DB sessions between different tests.
I cooked up a minimal, complete example to highlight the problem, note that test_user_schema1()
and test_user_schema2()
are the same.
Filename: test_db.py
from models import User
def test_user_schema1(session):
person_name = 'Fran Clan'
uu = User(name=person_name)
session.add(uu)
session.commit()
assert uu.id==1
assert uu.name==person_name
def test_user_schema2(session):
person_name = 'Stan Clan'
uu = User(name=person_name)
session.add(uu)
session.commit()
assert uu.id==1
assert uu.name==person_name
If the db is truly isolated between my tests, both tests should pass. However, the last test always fails, because I haven't found a way to make db sessions rollback correctly.
conftest.py
uses the following based on what I saw in Alex Michael's blog post, but this fixture code breaks because it apparently doesn't isolate the db sessions between fixtures.
@pytest.yield_fixture(scope='function')
def session(app, db):
connection = db.engine.connect()
transaction = connection.begin()
#options = dict(bind=connection, binds={})
options = dict(bind=connection)
session = db.create_scoped_session(options=options)
yield session
# Finalize test here
transaction.rollback()
connection.close()
session.remove()
For the purposes of this question, I built a gist, which contains all you need to reproduce it; you can clone it with git clone https://gist.github.com/34fa8d274fc4be240933.git
.
I am using the following packages...
Flask==0.10.1
Flask-Bootstrap==3.3.0.1
Flask-Migrate==1.3.0
Flask-Moment==0.4.0
Flask-RESTful==0.3.1
Flask-Script==2.0.5
Flask-SQLAlchemy==2.0
Flask-WTF==0.11
itsdangerous==0.24
pytest==2.6.4
Werkzeug==0.10.1
Two questions:
- Why is status quo broken? This same py.test fixture seemed to work for someone else.
- How can I fix this to work correctly?