diff --git a/django_nose/plugin.py b/django_nose/plugin.py index 4505ef2..1535228 100644 --- a/django_nose/plugin.py +++ b/django_nose/plugin.py @@ -312,7 +312,11 @@ def _bundle_fixtures(self, fftc_tests): return tests - def prepareTest(self, test): + def prepareTestRunner(self, runner): + """Get a runner that reorders tests before running them""" + return _DatabaseSetupTestRunner(self, runner) + + def group_by_database_setup(self, test): """Reorder the tests.""" test_groups = self._group_test_cases_by_type(test) suites = [] @@ -339,6 +343,23 @@ def prepareTest(self, test): return suites[0] if len(suites) == 1 else ContextSuite(suites) +class _DatabaseSetupTestRunner(object): + """A test runner that groups tests by database setup + + This is a helper class that reorders tests for efficient database + setup. It modifies the test suite before any other plugins have a + chance to wrap it in the `prepareTest` hook. + """ + + def __init__(self, plugin, real_runner): + self.plugin = plugin + self.runner = real_runner + + def run(self, test): + test = self.plugin.group_by_database_setup(test) + return self.runner.run(test) + + def get_test_context(context_path, tests, runner): """Make a test context. diff --git a/django_nose/runner.py b/django_nose/runner.py index e316c6b..e6adee2 100644 --- a/django_nose/runner.py +++ b/django_nose/runner.py @@ -42,8 +42,8 @@ import nose.core -from django_nose.plugin import DjangoSetUpPlugin, ResultPlugin from django_nose.plugin import DatabaseSetUpPlugin +from django_nose.plugin import DjangoSetUpPlugin, ResultPlugin from django_nose.utils import uses_mysql try: @@ -285,13 +285,15 @@ class BasicNoseRunner(BaseRunner): def run_suite(self, nose_argv): """Run the test suite.""" result_plugin = ResultPlugin() - plugins_to_add = [DjangoSetUpPlugin(self), result_plugin] + plugins_to_add = [ + DjangoSetUpPlugin(self), + DatabaseSetUpPlugin(self), + result_plugin, + ] for plugin in _get_plugins_from_settings(): plugins_to_add.append(plugin) - plugins_to_add.append(DatabaseSetUpPlugin(self)) - try: django.setup() except AttributeError: