from optparse import make_option from django.conf import settings from django.db.models.loading import load_app from django.utils.importlib import import_module try: # Django 1.6 from django.test.runner import DiscoverRunner except ImportError: # Fallback to third-party app on Django 1.5 from discover_runner import DiscoverRunner TESTAPPS_INSTALL = list(getattr(settings, 'TESTAPPS_INSTALL', () )) class TestAppRunnerMixin(object): """ A Django test runner mixin that, before testing and prior to 'syncdb', installs the 'tests' package from each of the apps specified. """ option_list = ( make_option( '--with-test-app', action='append', choices=settings.INSTALLED_APPS, dest='which_apps', default=settings.TESTAPPS_INSTALL, help="Specify a subset of INSTALLED_APPS whose 'tests' modules MUST be installed" " as apps during test execution." ), ) def __init__(self, which_apps, **options): self.which_apps = set(which_apps) # remove duplicates super(TestAppRunnerMixin, self).__init__(**options) def setup_test_environment(self, **kwargs): self.install_test_apps() super(TestAppRunnerMixin, self).setup_test_environment(**kwargs) def install_test_apps(self): test_apps = [] for app in self.which_apps: try: test_app = import_module('.tests', app) # check if it has a 'models' module and, if so, add it to the 'AppCache': if load_app(test_app.__name__): test_apps.append(test_app.__name__) except ImportError: pass # app with no 'tests' module settings.INSTALLED_APPS += tuple(test_apps) class DiscoverTestAppRunner(TestAppRunnerMixin, DiscoverRunner): option_list = DiscoverRunner.option_list + TestAppRunnerMixin.option_list