Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Lazy test database creation #34

Open
wants to merge 10 commits into from

1 participant

@andrejtokarcik

Introducing laziness in the test database creation process: The test database is created if and only if a test with no_database_interaction set to False is present in the set of the tests being run.

Some minor code improvements included as well (commenting out the leave_transaction_management() call might be disputable, though).

BTW, I'm thinking about making DjangoDatabasePlugin in order to separate the stuff always needed (with fast pure unit tests as well as with database tests; such as handling mail outboxes, etc.) and the procedures relevant only for the database tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 14, 2011
  1. Export mock_settings for easy import.

    Andrej Tokarcik authored
Commits on Mar 25, 2011
  1. Merge branch 'master' of ../django-sane-testing-almad

    Andrej Tokarcik authored
Commits on Apr 6, 2011
  1. Pretty dirty hack; just temporary and will probably conflict in the f…

    Andrej Tokarcik authored
    …uture :(
Commits on Apr 11, 2011
  1. Merge branch 'master' of ../django-sane-testing-almad

    Andrej Tokarcik authored
Commits on May 6, 2011
  1. Merge branch 'master' of ../django-sane-testing-almad

    Andrej Tokarcik authored
Commits on May 10, 2011
  1. Merge branch 'master' of ../django-sane-testing-almad

    Andrej Tokarcik authored
Commits on May 18, 2011
  1. Introduce lazy database creation.

    Andrej Tokarcik authored
  2. Merge branch 'master' of ../django-sane-testing-almad

    Andrej Tokarcik authored
  3. Additional DjangoPlugin's code cleanup.

    Andrej Tokarcik authored
Commits on Jul 12, 2011
  1. @andrejtokarcik
This page is out of date. Refresh to see the latest.
View
1  djangosanetesting/__init__.py
@@ -4,3 +4,4 @@
from djangosanetesting.cases import *
from djangosanetesting.testrunner import *
+from djangosanetesting.utils import *
View
73 djangosanetesting/noseplugins.py
@@ -27,7 +27,7 @@
#from djagnosanetesting.cache import flush_django_cache
from djangosanetesting.selenium.driver import selenium
from djangosanetesting.utils import (
- get_live_server_path, test_database_exists,
+ get_live_server_path,
DEFAULT_LIVE_SERVER_ADDRESS, DEFAULT_LIVE_SERVER_PORT,
)
@@ -269,6 +269,8 @@ class DjangoPlugin(Plugin):
name = 'django'
env_opt = 'DST_PERSIST_TEST_DATABASE'
+ db_created = False
+
def options(self, parser, env=os.environ):
Plugin.options(self, parser, env)
@@ -321,17 +323,25 @@ def teardown_databases(self, old_config, verbosity, **kwargs):
for connection, old_name in old_names:
connection.creation.destroy_test_db(old_name, verbosity)
+ def begin(self, *args):
+ flush_cache()
+ self.need_flush = False
- def begin(self):
- from django.test.utils import setup_test_environment
- setup_test_environment()
+ def finalize(self, *args):
+ if self.db_created and not self.persist_test_database:
+ self.teardown_databases(self.old_config, verbosity=False)
- def prepareTestRunner(self, runner):
+ def beforeTest(self, test):
"""
Before running tests, initialize database et al, so noone will complain
"""
- # FIXME: this should be lazy for tests that do not need test
- # database at all
+ test_case = get_test_case_class(test)
+ if getattr(test_case, 'no_database_interaction', False) or \
+ self.db_created:
+ # stop execution if the database is not needed or already exists
+ return
+ self.db_created = True
+
from django.db import connection
from django.conf import settings
self.old_name = settings.DATABASE_NAME
@@ -341,7 +351,7 @@ def prepareTestRunner(self, runner):
except ImportError:
connections = {DEFAULT_DB_ALIAS : connection}
- if not self.persist_test_database or test_database_exists():
+ if not self.persist_test_database:
#connection.creation.create_test_db(verbosity=False, autoclobber=True)
self.old_config = self.setup_databases(verbosity=False, autoclobber=True)
@@ -352,23 +362,6 @@ def prepareTestRunner(self, runner):
if getattr(settings, "FLUSH_TEST_DATABASE_AFTER_INITIAL_SYNCDB", False):
getattr(settings, "TEST_DATABASE_FLUSH_COMMAND", flush_database)(self, database=db)
- flush_cache()
-
- self.need_flush = False
-
- def finalize(self, result):
- """
- At the end, tear down our testbed
- """
- from django.test.utils import teardown_test_environment
- teardown_test_environment()
-
- if not self.persist_test_database:
- self.teardown_databases(self.old_config, verbosity=False)
-# from django.db import connection
-# connection.creation.destroy_test_db(self.old_name, verbosity=False)
-
-
def startTest(self, test):
"""
When preparing test, check whether to make our database fresh
@@ -389,10 +382,12 @@ def startTest(self, test):
from django.test.testcases import call_command
from django.core import mail
from django.conf import settings
-
+
+ from django.test.utils import setup_test_environment
+ setup_test_environment()
+
test_case = get_test_case_class(test)
self.previous_test_needed_flush = self.need_flush
- mail.outbox = []
enable_test(test_case, 'django_plugin_started')
# clear URLs if needed
@@ -400,16 +395,15 @@ def startTest(self, test):
test_case._old_root_urlconf = settings.ROOT_URLCONF
settings.ROOT_URLCONF = test_case.urls
clear_url_caches()
-
+
#####
### Database handling follows
#####
-
if getattr(test_case, 'no_database_interaction', False):
# for true unittests, we can leave database handling for later,
- # as unittests by definition do not interacts with database
+ # as unittests by definition do not interact with database
return
-
+
# make self.transaction available
test_case.transaction = transaction
self.commits_could_be_used = False
@@ -444,8 +438,7 @@ def startTest(self, test):
else:
self.need_flush = False
-
- if (hasattr(test_case, "database_single_transaction") and test_case.database_single_transaction is True):
+ if getattr(test_case, 'database_single_transaction', False):
transaction.enter_transaction_management()
transaction.managed(True)
@@ -467,17 +460,23 @@ def stopTest(self, test):
from django.db import transaction
from django.conf import settings
- test_case = get_test_case_class(test)
+ from django.test.utils import teardown_test_environment
+ teardown_test_environment()
- if (hasattr(test_case, "database_single_transaction") and test_case.database_single_transaction is True):
- transaction.rollback()
- transaction.leave_transaction_management()
+ test_case = get_test_case_class(test)
if hasattr(test_case, '_old_root_urlconf'):
settings.ROOT_URLCONF = test_case._old_root_urlconf
clear_url_caches()
flush_cache(test_case)
+ if getattr(test_case, 'no_database_interaction', False):
+ return
+
+ if getattr(test_case, 'database_single_transaction', False):
+ transaction.rollback()
+ #transaction.leave_transaction_management()
+
class DjangoTranslationPlugin(Plugin):
"""
For testcases with selenium_start set to True, connect to Selenium RC.
View
4 djangosanetesting/utils.py
@@ -2,6 +2,8 @@
from functools import wraps
import urllib2
+__all__ = ('mock_settings',)
+
DEFAULT_LIVE_SERVER_PROTOCOL = "http"
DEFAULT_LIVE_SERVER_PORT = 8000
DEFAULT_LIVE_SERVER_ADDRESS = '0.0.0.0'
@@ -18,7 +20,7 @@ def extract_django_traceback(twill=None, http_error=None, lines=None):
http_error = urllib2.HTTPError(url=twill.get_url(), code=500, msg=None, hdrs=None, fp=None)
if not lines:
lines = twill.result.get_page().split("\n")
-
+
lines = lines or []
for one in lines:
View
0  testonetwoproject/models.py 100755 → 100644
File mode changed
View
0  testproject/models.py 100755 → 100644
File mode changed
View
0  testproject/testapp/models.py 100755 → 100644
File mode changed
Something went wrong with that request. Please try again.