Reputation: 51847
Our database connection code is wrapped in a context manager. It's handy in that all you have to do is something like:
with db.transaction() as cursor:
do_things_here()
And it handles all the nesting & rolling back of transactions on error for you.
However, it's causing some slight problems for me because I want to wrap my entire module. I thought I could do something like:
@pytest.fixture(scope='module')
def db():
with db.transaction():
yield db
db.rollback()
But that didn't work - pytest says I can't yield from a fixture.
We're using postgres & psycopg2 under the hood.
Is there a way to either use a context manager for the whole module, or solve my issue some other way?
I also tried doing something like this:
@pytest.fixture(scope='module')
def db(request):
cursor = db.transaction()
def teardown():
cursor.__exit__(None, None, None)
request.addfinalizer(teardown)
but the contextmanager decorator didn't like that.
Finally, I even tried
with db.transaction(force_rollback=True):
def test_my_things():
db.execute('CREATE TABLE castle_auuurrrhhgggg;')
but executing that twice failed because the table exists.
However, if I do:
def test_my_things():
with db.transaction(force_rollback=True) as cursor:
cursor.execute('CREATE TABLE knights_who_say_ni;')
It works just fine.
Any ideas of how I can roll everything back at the end of my testing?
Upvotes: 3
Views: 367
Reputation: 47820
If you use the yieldfixture
instead of a regular fixture
it should work with your initial attempt.
Upvotes: 1