Skip to content

Instantly share code, notes, and snippets.

@tganzarolli
Created April 27, 2011 20:15
Show Gist options
  • Save tganzarolli/945093 to your computer and use it in GitHub Desktop.
Save tganzarolli/945093 to your computer and use it in GitHub Desktop.
Generates a custom DjangoTestSuiteRunner that can bypassa the creation of a database instance, if the BYPASS_CREATION entry is set to yes, inside DATABASES dict.
from django.test.simple import DjangoTestSuiteRunner
class ByPassableDBDjangoTestSuiteRunner(DjangoTestSuiteRunner):
def setup_databases(self, **kwargs):
from django.db import connections
old_names = []
mirrors = []
for alias in connections:
connection = connections[alias]
# If the database is a test mirror, redirect it's connection
# instead of creating a test database.
if connection.settings_dict['TEST_MIRROR']:
mirrors.append((alias, connection))
mirror_alias = connection.settings_dict['TEST_MIRROR']
connections._connections[alias] = connections[mirror_alias]
elif connection.settings_dict.get('BYPASS_CREATION','no') == 'no':
old_names.append((connection, connection.settings_dict['NAME']))
connection.creation.create_test_db(self.verbosity, autoclobber=not self.interactive)
return old_names, mirrors
@theandyl
Copy link

theandyl commented Jul 5, 2012

Hi,
for Django 1.4 it should be:

from django.test.simple import DjangoTestSuiteRunner, dependency_ordered

class ByPassableDBDjangoTestSuiteRunner(DjangoTestSuiteRunner):

    def setup_databases(self, **kwargs):
        from django.db import connections, DEFAULT_DB_ALIAS

        # First pass -- work out which databases actually need to be created,
        # and which ones are test mirrors or duplicate entries in DATABASES
        mirrored_aliases = {}
        test_databases = {}
        dependencies = {}
        for alias in connections:
            connection = connections[alias]
            if connection.settings_dict['TEST_MIRROR']:
                # If the database is marked as a test mirror, save
                # the alias.
                mirrored_aliases[alias] = (
                    connection.settings_dict['TEST_MIRROR'])
            elif connection.settings_dict.get('BYPASS_CREATION','no') == 'no': # MODIFIED TO SUPPORT "BYPASS_CREATION"
                # Store a tuple with DB parameters that uniquely identify it.
                # If we have two aliases with the same values for that tuple,
                # we only need to create the test database once.
                item = test_databases.setdefault(
                    connection.creation.test_db_signature(),
                    (connection.settings_dict['NAME'], [])
                )
                item[1].append(alias)

                if 'TEST_DEPENDENCIES' in connection.settings_dict:
                    dependencies[alias] = (
                        connection.settings_dict['TEST_DEPENDENCIES'])
                else:
                    if alias != DEFAULT_DB_ALIAS:
                        dependencies[alias] = connection.settings_dict.get(
                            'TEST_DEPENDENCIES', [DEFAULT_DB_ALIAS])

        # Second pass -- actually create the databases.
        old_names = []
        mirrors = []
        for signature, (db_name, aliases) in dependency_ordered(
            test_databases.items(), dependencies):
            # Actually create the database for the first connection
            connection = connections[aliases[0]]
            old_names.append((connection, db_name, True))
            test_db_name = connection.creation.create_test_db(
                self.verbosity, autoclobber=not self.interactive)
            for alias in aliases[1:]:
                connection = connections[alias]
                if db_name:
                    old_names.append((connection, db_name, False))
                    connection.settings_dict['NAME'] = test_db_name
                else:
                    # If settings_dict['NAME'] isn't defined, we have a backend
                    # where the name isn't important -- e.g., SQLite, which
                    # uses :memory:. Force create the database instead of
                    # assuming it's a duplicate.
                    old_names.append((connection, db_name, True))
                    connection.creation.create_test_db(
                        self.verbosity, autoclobber=not self.interactive)

        for alias, mirror_alias in mirrored_aliases.items():
            mirrors.append((alias, connections[alias].settings_dict['NAME']))
            connections[alias].settings_dict['NAME'] = (
                connections[mirror_alias].settings_dict['NAME'])
            connections[alias].features = connections[mirror_alias].features

        return old_names, mirrors

@nicbou
Copy link

nicbou commented Jun 28, 2014

For Django 1.6+, you can use DiscoverRunner instead of DjangoTestSuiteRunner, and it won't break

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment