I try to speedup my tests by putting test data from test case setUp()
to setUpClass()/teardownClass
class method, so it does not recreate same select only fixture for every test in test case.
@classmethod
def setUpClass(cls):
plant.StuffFactory() #plant stuff with FactoryBoy
transaction.commit()
@classmethod
def tearDownClass(cls):
session.query(models.Stuff).delete() # delete planted stuff
transaction.commit()
But i don't like deleting stuff with session.delete on my own, because i use many models and don't want track what i planted. I want something like
@classmethod
def tearDownClass(cls):
session.clear() #delete all
transaction.commit()
But session.close()
or session.remove()
will not affect committed data.
So i seek some way to "cancel" setUpClass
transaction.commit()
like i don't plant anything.
I try nested transactions and savepoints but again they works only if data not committed yet.
Any pointers?
If you don't want things to be committed, simply don't call transaction.commit()
:)
@classmethod
def setUpClass(cls):
plant.StuffFactory() #plant stuff with FactoryBoy
# you may possibly want to flush the session, so everything has proper IDs etc.
DBSession.flush()
# let the transaction continue for the duration of the test
@classmethod
def tearDownClass(cls):
# let the database make everything as if nothing happened
transaction.rollback()
This would require that none of your code under test does explicit transaction management (transaction.commit()
\ transaction.rollback()
in application code), but that's a bad practice anyway:
As a general rule, the application should manage the lifecycle of the session externally to functions that deal with specific data. This is a fundamental separation of concerns which keeps data-specific operations agnostic of the context in which they access and manipulate that data.
Session Basics, SQLAlchemy Documentation (https://docs.sqlalchemy.org/en/13/orm/session_basics.html)