One of the item on the list for 1.1 is "Run Django test cases inside a
transaction".  The ticket for this is #8138:

http://code.djangoproject.com/ticket/8138

and previous list discussion can be found here:

http://groups.google.com/group/django-developers/browse_thread/thread/49aa551ad41fb919/3d75d940a1cc23d5

The general idea is to speed up the running of Django tests by using
transaction rollbacks at the end of tests instead of flush/syncdb at the
beginning of each test.  While this approach generally works fine, it did
introduce a set of (some weird) failures into the Django test suite that
needed to be tracked down before it could be seriously considered for
checkin.  That, I believe, is done now (see ticket for details).  Broadly
the failures could be categorized into two piles:

1 - Some resulted from subtle differences in the old and new approaches and
could be fixed by tweaking the new approach.

2 - Others resulted from tests that made invalid assumptions -- like that
primary keys for objects created by the test would be assigned starting at
one.  These failures needed to be addressed by fixing the testcases to not
rely on such assumptions.  The need to do that, though, highlights that this
change may not be 100% transparent to anyone with their own set of tests,
unless they've been diligent about never relying on such things.  (A to-do
still remaining for this ticket is to write some doc for stuff like this.)

With all the failures figured out, the new rollback approach shows
significant speedups for running the Django test suite.  Early measurements
I did showed a factor of 6 speedup for sqlite, nearer 10-12 for
MySQL/InnoDB, PostgreSQL, and Oracle.  I tried measuring the latest patch
today on sqlite and see an 8x speedup there and 16x on MySQL/InnoDB, but
don't have time to test the others at present.  (MySQL/MyISAM has no
improvement -- since it doesn't support transactions the old flush/syncdb
approach still needs to be used when running on that combination.)

The one big remaining issue I'm not entirely sure what to do about is
doctests.  These, today, don't have any sort of automatic flush/syncdb
isolation done for them.  So DB changes made by one doctest may be seen by
other tests (though an intervening unit test that did flush/syncdb might
clear things out.)  The initial approach taken by the early patches on #8183
was to enclose doctest runs in a rolled-back transaction, just as was being
done for unit tests.  At first glance this seems like a good idea (it
provides isolation that is known to be lacking currently), but upon further
investigation it has a couple of problems:

First, there is no "escape route" for a doctest to indicate that it needs to
control transaction boundaries.  This is provided in the unit test
alternative by providing a TransactionTestCase that can be used for tests
that do not want the test running machinery interfering with its own use of
transactions.  So if a unit test needs to control transactions, it can do so
by by basing off of TransactionTestCase, in which case  flush/syncdb is used
to initialize the DB instead of using the rolled back transaction.  There
doesn't seem to be any nice clean way to provide a similar escape route for
doctests.

Second, if we start isolating doctests like this for DBs that support
transactions, what do we do in the case(s) where the DB doesn't support
transactions?  If we fall back to flush/syncdb as we do for unit tests,
that's going to slow down the test suite even more for the MySQL/MyISAM
combo.  If we don't fallback to flush/syncdb so as not to incur the
performance penalty, then we start introducing a serious divergence in test
environment depending on the DB used.  I really don't like either one of
these alternatives.

So, the latest patch on #8183 (8138alternate-nodoctestxaction.diff) does not
enclose doctest runs in a rolled-back transaction.  Thus the effects of
doctests can still bleed over into subsequent tests.  This doesn't actually
cause any failures or errors when running the Django test suite, as far as
I've seen.  I'm inclined to think it's an OK alternative at least for the
short term, but would be interested in hearing other opinions.  (Longer term
I'm thinking perhaps something along the lines of Joseph's patch on #5624
for specifying doctest fixtures could be developed into a general mechanism
for a doctest to specify some operational needs including fixtures,
transactional control, isolation...or that may be overkill.)

Some other to-dos I have on my list:

1 - Documentation is currently completely lacking.
2 - Think some more about TransactionTestCase.  This isn't used by any of
the Django tests but I think needs to be provided in case anyone has tests
that really do need to make use of transactions internally.  I think,
though, there is currently a bit of a problem with mixing
TransactionTestCases with TestCases since the former clears the DB on entry
but not afterward, so its effects are not cleaned up, while TestCases assume
the DB is clean on entry.
3 - Anything else anyone notices?

Karen

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to