I think I solved this! The reason why the test cases were taking so long was
because Django was not enabling the transaction support, so the tests were
falling back to the non-transaction TestCase

My project has two test databases but the 'log' is not used anymore so I
didn't care if it was created or not:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': ':memory:',
    },

    'log': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': ':memory:',
    }
}

When the tests run it calls the following method:

def connections_support_transactions():
    """
    Returns True if all connections support transactions.  This is messy
    because 2.4 doesn't support any or all.
    """
    return all(conn.features.supports_transactions
        for conn in connections.all())

In Django 1.2.3 this method returns all([True, True]) and in Django 1.3 it
returns all([True, None])

The problem is that in my test settings I used the same database name
':memory:' on both databases. When this happens in Django 1.2.3 it
initialize the both databases, but in Django 1.3 it doesn't initialize the
second. I just had to change the names and now the tests are running back in
the usual speed!

This was very hard to debbug, maybe Django should include a warning message
in case someone tries to do this mistake again?


Thanks!
Cesar Canassa

2011/6/24 Russell Keith-Magee <russ...@keith-magee.com>

> On Fri, Jun 24, 2011 at 11:54 AM, Cesar Canassa <cesar.cana...@gmail.com>
> wrote:
> > Hi Russ!
> > I did some more testing, I found out that each test is taking an extra
> ~1s
> > to run, no matter the test size. See this TestCase for example, it
> > takes 4.067s to run.
> > from django.test import TestCase
> > class JobTest(TestCase):
> >     def test_1(self):
> >         pass
> >     def test_2(self):
> >         pass
> >     def test_3(self):
> >         pass
> >     def test_4(self):
> >         pass
> > I noticed that if I replace the django.test.TestCase with
> > the django.utils.unittest.TestCase the time drops to 0.009s I think that
> the
> > problem lies in the TransactionTestCase._fixture_setup method:
> >     def _fixture_setup(self):
> >         # If the test case has a multi_db=True flag, flush all databases.
> >         # Otherwise, just flush default.
> >         if getattr(self, 'multi_db', False):
> >             databases = connections
> >         else:
> >             databases = [DEFAULT_DB_ALIAS]
> >         for db in databases:
> >             call_command('flush', verbosity=0, interactive=False,
> > database=db)
> >             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,
> > 'database': db})
> > The flush is what takes ~1s to run, If I comment that line the time drops
> to
> > almost zero seconds.
> > Does this makes any sense? Did the Django 1.3 changed this behavior?
> > I am downloading the Django 1.2.5 source to do more investigation.
>
> Thanks for that analysis, Cesar.
>
> Flush has always been a bit of a performance hole -- especially on
> MySQL MyISAM. However, I'm not aware of any change we made in 1.3 that
> should make any worse than it was in 1.2. The biggest factor affecting
> the speed of a flush (that I'm aware of) is the number of tables to be
> flushed; as Django's test suite has gotten bigger, the suite as a
> whole has gotten exponentially slower, as more tests means more test
> models to flush. However, this factor shouldn't affect an A/B test
> between 1.2 and 1.3 of the same test suite.
>
> Good luck narrowing this down some more :-)
>
> Yours,
> Russ Magee %-)
>
> --
> 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.
>
>

-- 
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.

Reply via email to