I encountered an asymmetry between TestCase
and TransactionTestCase
regarding when fixtures are made available. I’d like to propose eliminating the potential gotcha. [ticket] [pull request]
On databases that support transactions, TestCase
loads fixtures only once, during setUpClass()
. This is so that each test can roll back to the end of setUpClass()
/setUpTestData()
.
TransactionTestCase
flushes after each test instead of using transactions, so there’s less of a use case for loading fixtures on a class basis on the idea that you likely also want fixture data available during the tests themselves. I figure this is why TransactionTestCase
doesn’t bother to override setUpClass()
.
However, I had cases where during class setup I wanted to call application logic that prepares temp directories and where this logic depended on fixtures (or more precisely, data from migrations, enabled with serialized_rollback=True
, but the situation is the same as with the fixtures
class attribute).
By trial and error, I found that the test data I was depending on weren’t available during setUpClass()
but only during setUp()
. I would have discovered this faster if I was using fixtures
, but I happened to be using data from initial migrations with serialized_rollback
, so the situation was more deceiving: my class with a single test method passed in isolation, since flushing only happens after each test, not before, and only failed in combination with other tests in the same pattern.
I think we can improve this situation:
- The docs don’t caution that fixture data are only available in certain parts of the test lifecycle.
- I think there’s a use case for depending on initial data in class setup even if
TransactionTestCase
will flush between tests, e.g. to perform side effects. - The
serialized_rollback
case is deceiving, causing difficult to debug failures when tests are combined after the fact.
Do folks agree this asymmetry is worth addressing?