Django’s TestCase class wraps each test in a transaction and rolls back that transaction after each test, in order to provide test isolation.
Apparently, however, only operations in the default database are within the scope of the transaction. I have a multiple database setup with a router that directs ORM calls on some models to a second database. This means that in the following example, test2 fails:
class MyTestCase(TestCase):
def test1(self):
# Let's say Foo model ORM calls are routed to a different DB
foo = Foo.objects.create(...)
assert foo.is_ok()
def test2(self):
assert not Foo.objects.exists()
The most immediate solution to this problem would be to override the tearDown method in MyTestCase and manually make sure to delete all Foo objects. But this is a bit annoying because it's sort of a hack and database sequences (e.g. autoincrement columns) won't be reset for example, only after the test suite is done and the database is destroyed.
Is there a way to properly fix this, making sure all database operations are by default made inside a transaction and rolled back at the end of each test?
[UPDATE]
Here's my router:
class FooRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'foo':
return 'foo_db'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'foo':
return 'foo_db'
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'foo':
return db == 'foo_db'
return None
test2fails. Sorry I wasn't very explicit. Just updated the question to be clearer.