from django.conf import settings from django.core.management.base import BaseCommand, CommandError from django.test import TestCase as django_TestCase import importlib import unittest class Command(BaseCommand): """ Command for running quick tests without a separate test database. Subclasses of django.test.Testcase are not supported since they attempt to flush the database. """ args = '' help = 'Run unittests for specified application without creating test \ database. Subclasses of django.test.TestCase are not supported.' INVALED_APP_MSG = 'The first argument must be a valid application name' NO_TESTS_MSG = 'No tests.py file was found in the application you specified' def handle(self, *args, **kwargs): """ Required for management command """ if len(args) == 0: raise CommandError(self.INVALED_APP_MSG) app_name = args[0] self.TestApp(app_name) def TestApp(self, app_name): """Run tests for the specified application.""" if not app_name in settings.INSTALLED_APPS: raise CommandError(self.INVALED_APP_MSG) try: tests = importlib.import_module('.'.join([app_name, 'tests'])) except: raise CommandError(self.NO_TESTS_MSG) suite = self.LoadNonJangoTestsFromModule(tests) runner = unittest.TextTestRunner(verbosity=2) result = runner.run(suite) return result def LoadNonJangoTestsFromModule(self, module): """ Load tests from module which are not subclass of django.test.TestCase """ tests = [] loader = unittest.TestLoader() for name in dir(module): obj = getattr(module, name) if isinstance(obj, type)\ and issubclass(obj, unittest.TestCase)\ and not issubclass(obj, django_TestCase): tests += loader.loadTestsFromTestCase(obj) return unittest.TestSuite(tests)