So, I've been trying to speed up tests. Surprise. I came across a fairly easy solution, so I'm sure I must be missing something. If someone could tell me what I'm missing, I'd really appreciate it.
So, first I created my own subclass of django.test.TestCase: class MyTestCase(django.test.TestCase): # see code below Then I wrote unit tests, subclassing MyTestCase class TestParticularThing(MyTestCase): fixtures = ['mydata', 'myotherdata.json'] dirties_db = True def test_something(self): TestParticularThing.dirties_db = False resp = self.client.get('/some/url') self.assertContains(resp, 'blah') def test_something_else(self): TestParticularThing.dirties_db = True resp = self.client.post('/another/url', {'var': 'value'}) self.assertRedirects(resp, '/redirect/url') So here's the code for MyTestCase. I just overrode the _pre_setup method so that it checks the dirties_db attribute of the class. If it both exists and is set to False, flushing and repopulating the db is skipped, otherwise the db is cleaned as usual. class MyTestCase(django.test.TestCase): def _pre_setup(self): """Performs any pre-test setup. This includes: * Flushing the database. * If the Test Case class has a 'fixtures' member, installing the named fixtures. * If the Test Case class has a 'urls' member, replace the ROOT_URLCONF with it. * Clearing the mail test outbox. """ if not hasattr(self.__class__, 'dirties_db') or self.__class__.dirties_db: print "Cleaning db" call_command('flush', verbosity=0, interactive=False) if hasattr(self, 'fixtures'): # We have to use this slightly awkward syntax due to the fact # that we're using *args and **kwargs together. call_command('loaddata', *self.fixtures, **{'verbosity': 0}) if hasattr(self.__class__, 'dirties_db'): self.__class__.dirties_db = True if hasattr(self, 'urls'): self._old_root_urlconf = settings.ROOT_URLCONF settings.ROOT_URLCONF = self.urls clear_url_caches() mail.outbox = [] So, to use this, add a class attribute dirties_db = True to your own subclass of MyTestCase. In any test methods that don't dirty the db, add: MyTestCaseSubclass.dirties_db = False and the next test method that's run in that class won't bother to flush and repopulate the database. To be explicit, you can set MyTestCaseSubclass.dirties_db = True in methods that dirty the database, but if you forget to explicitly set the value to False, it will be True and the db will be cleaned. Just trying it on some model and request/response tests, I got a speed-up from nearly a minute to less than 20 seconds for 13 tests. So, what am I missing? I know this doesn't deal with doctests--the db gets cleaned for all of those, but does anyone see when this is just going to blow up in my face? Thanks, Todd --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---