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 = '<application name>'
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)
Comments