Home > front end >  Django 1.4: Tests are very slow
Django 1.4: Tests are very slow

Time:10-23

I am working on a old code base which still uses Django 1.4

This means the nice flag --keepdb is not available.

Running a single test like this takes 50 seconds:

time manage.py test myapp.tests.test_foo.FooTestCase.test_something

My test_something method is fast. It is the creation of the test-DB which takes so long.

50 seconds is too long for a productive edit-test-cycle. What can I do (except faster hardware)?

CodePudding user response:

You can hack the option --keepdb into your source code.

You need to edit the file django/db/backends/creation.py like this:

256c256,259
<         self._create_test_db(verbosity, autoclobber)
---
>         skip = True
> 
>         if not skip:
>             self._create_test_db(verbosity, autoclobber)
264,281c267,285
<         # Report syncdb messages at one level lower than that requested.
<         # This ensures we don't get flooded with messages during testing
<         # (unless you really ask to be flooded)
<         call_command('syncdb',
<             verbosity=max(verbosity - 1, 0),
<             interactive=False,
<             database=self.connection.alias,
<             load_initial_data=False)
< 
<         # We need to then do a flush to ensure that any data installed by
<         # custom SQL has been removed. The only test data should come from
<         # test fixtures, or autogenerated from post_syncdb triggers.
<         # This has the side effect of loading initial data (which was
<         # intentionally skipped in the syncdb).
<         call_command('flush',
<             verbosity=max(verbosity - 1, 0),
<             interactive=False,
<             database=self.connection.alias)
---
>         if not skip:
>             # Report syncdb messages at one level lower than that requested.
>             # This ensures we don't get flooded with messages during testing
>             # (unless you really ask to be flooded)
>             call_command('syncdb',
>                 verbosity=max(verbosity - 1, 0),
>                 interactive=False,
>                 database=self.connection.alias,
>                 load_initial_data=False)
> 
>             # We need to then do a flush to ensure that any data installed by
>             # custom SQL has been removed. The only test data should come from
>             # test fixtures, or autogenerated from post_syncdb triggers.
>             # This has the side effect of loading initial data (which was
>             # intentionally skipped in the syncdb).
>             call_command('flush',
>                 verbosity=max(verbosity - 1, 0),
>                 interactive=False,
>                 database=self.connection.alias)
391,393c395,398
<         time.sleep(1)
<         cursor.execute("DROP DATABASE %s"
<                        % self.connection.ops.quote_name(test_database_name))
---
> 
>         #time.sleep(1)
>         #cursor.execute("DROP DATABASE %s"
>         #               % self.connection.ops.quote_name(test_database_name))

Now running the test takes 6 instead of 50 seconds.

If you modify the database schema, then you need to set skip = False for one run.

  • Related