Currently the Django testsuite flushes the database after every test. That is a major performance drawback. The fixture loading/truncating takes much longer than the actual test. So I propose to switch the Django testtools to use transactions:
- Before every test a transaction is started
- The fixtures (if existing) are loaded
- No commit is performed
- The tests run
- A rollback is performed
There is a matching discussion on django-developers:
http://groups.google.com/group/django-developers/browse_thread/thread/49aa551ad41fb919
My first tests with the concept show some promise. The first try at a patch breaks some tests (1 on SQLite, 25 on PostgreSQL), but the performance improvement is significant. With the django testsuite the results on my Laptop (slow disk - IO is the bottleneck with the tests here) so far are:
- SQLite in-memory-db:
- before: 415 sec
- after: 79 sec
- PostgreSQL:
- before: 4285 sec
- after: 359 sec
As suggested by Russell Keith-Magee, I renamed the original test.TestCase? to test.TransactionTestCase? and implemented the new functionality in test.TestCase?. If someone explicitly wants to use transactions inside a test, he can use TransactionTestCase? and will only loose the performance gain.
With the current patch all doctests now use transactional behaviour. We'll see, if I can implement a choice there, too - if it is necessary.