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.

Reply via email to