I've been looking into the django testing infrastructure today to see if
there was any particular reason why the test suite takes so long to run.
Mainly, I didn't understand why fixtures are loaded for every single test
method. To be honest, I didn't think fixtures were loaded for every test
method; I assumed they were loaded once when the TestCase was created.
My mental model looked like this:
# for each test module:
call_command(flush) # flush the DB ready for this test case
testcase = get_test_case() # returns the next subclass of TestCase (or
TransactionTestCase etc)
*testcase.load_fixtures() # populate the DB with data for the entire test
case*
for test_method in testcase.get_test_methods():
with db.transaction(): # at the end of each test_method, rollback so
that we're back to our fixtures
testcase.setUp()
getattr(testcase, test_method)()
testcase.tearDown()
Unfortunately, that's not at all what happens. For each test method, you're
given a brand new instance of the testcase, and the initial data is loaded
again:
# for each test module:
call_command(flush) # flush the DB ready for this test case
testcaseclass = get_test_case()
for test_method in testcaseclass.get_test_methods():
with db.transaction(): # at the end of each test_method, rollback to
an empty database
testcase = testcaseclass(testMethod=test_method)
*testcase.load_fixtures() # populate the DB with data for a single
test_method*
testcase.setUp()
testcase.run() # runs the testMethod
testcase.tearDown()
Note that the above isn't exactly right, but I think it demonstrates the
problem. Each test_method is given its own TestCase (unnecessary python
overhead), but more importantly, we're not using transactions to get back
to the initial data. We're using transactions to get back to an empty
database before loading fixtures again.
I know lots of people have invested lots of time on the test suite,
especially when it comes to run time. I doubt that I'm raising anything new
for the people who have come before. But my question is why? Is there a
reason that each test method has to have its own TestCase? Is there a
reason that each test method has to load its own fixtures again and again,
or is that just a symptom of how each test_method is collected by the test
suite?
There are many kinds of tests that deal with the ORM that should be able to
rely on fixtures being loaded once for the entire TestCase, and relying on
transactions to get back to initial data. Is this theoretically possible,
or am I missing something? I figure we could eliminate something like 1/3rd
of all queries.
Regards,
Josh
--
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/07c8e766-43e6-4362-bba1-695d3855a77a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.