improving performance of django tests with nested transactions/savepoints
This monkey-patches django.tests.testcases.TestCase
so that all tests in a TestCase
take place in a BEGIN
transaction, while test methods take place in a nested transaction, with a savepoint being recorded after fixtures are loaded before a test, and rolling back to it after the test completes.
Although previously I suggested memoizing yaml loading, we still would have to execute database insertions for fixtures; this method minimizes it to a per-TestCase level, instead of per-test method.
Note that this will only have a significant impact if your tests use fixtures, but when it does, it'll blow your socks off.
For a simple benchmark, I'll be using satchmo's satchmo_store.shop.tests
. It has 9 test cases, with the bulk in two of them - 20 tests in one, and 14 in the other. The former also uses Client
, another major performance hog. Both use fixtures.
I'll also be using django 1.2, with nested transaction support for sqlite3.
Here are the numbers:
- 65.013s: no optimizations applied
- 61.904s: memoized yaml
- 47.229s: nested transactions in TestCase
- 43:917s: nested transactions in TestCase, memoized yaml