Skip to content

Instantly share code, notes, and snippets.

@IuryAlves
Created July 25, 2017 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IuryAlves/61b0a4b8723b868604168b9e6292d1a1 to your computer and use it in GitHub Desktop.
Save IuryAlves/61b0a4b8723b868604168b9e6292d1a1 to your computer and use it in GitHub Desktop.
Run Django tests without migrations
#!/usr/bin/env python
import os
import sys
from django.core.management import ManagementUtility
from django_test_runner import is_nosetest
from pycharm_run_utils import import_system_module
from teamcity import teamcity_presence_env_var
inspect = import_system_module("inspect")
project_directory = sys.argv.pop()
#ensure project directory is given priority when looking for settings files
sys.path.insert(0, project_directory)
#import settings to prevent circular dependencies later on import django.db
try:
from django.conf import settings
apps = settings.INSTALLED_APPS
except:
pass
from django.core import management
from django.core.management.commands.test import Command
try:
# setup environment
# this stuff was done earlier by setup_environ() which was removed in 1.4
sys.path.append(os.path.join(project_directory, os.pardir))
project_name = os.path.basename(project_directory)
__import__(project_name)
except ImportError:
# project has custom structure (project directory is not importable)
pass
finally:
sys.path.pop()
manage_file = os.getenv('PYCHARM_DJANGO_MANAGE_MODULE')
if not manage_file:
manage_file = 'manage'
try:
__import__(manage_file)
except ImportError as e:
print ("Failed to import" + str(manage_file) + " in ["+ ",".join(sys.path) +"] " + str(e))
settings_file = os.getenv('DJANGO_SETTINGS_MODULE')
if not settings_file:
settings_file = 'settings'
import django
if django.VERSION[0:2] >= (1, 7):
if not settings.configured:
settings.configure()
django.setup()
class DisableMigrations(object):
def __contains__(self, item):
return True
def __getitem__(self, item):
return "notmigrations"
class PycharmTestCommand(Command):
def get_runner(self):
TEST_RUNNER = 'django_test_runner.run_tests'
test_path = TEST_RUNNER.split('.')
# Allow for Python 2.5 relative paths
if len(test_path) > 1:
test_module_name = '.'.join(test_path[:-1])
else:
test_module_name = '.'
test_module = __import__(test_module_name, {}, {}, test_path[-1])
test_runner = getattr(test_module, test_path[-1])
return test_runner
def handle(self, *test_labels, **options):
# handle south migration in tests
commands = management.get_commands()
settings.MIGRATION_MODULES = DisableMigrations()
if hasattr(settings, "SOUTH_TESTS_MIGRATE") and not settings.SOUTH_TESTS_MIGRATE:
# point at the core syncdb command when creating tests
# tests should always be up to date with the most recent model structure
commands['syncdb'] = 'django.core'
elif 'south' in settings.INSTALLED_APPS:
try:
from south.management.commands import MigrateAndSyncCommand
commands['syncdb'] = MigrateAndSyncCommand()
from south.hacks import hacks
if hasattr(hacks, "patch_flush_during_test_db_creation"):
hacks.patch_flush_during_test_db_creation()
except ImportError:
commands['syncdb'] = 'django.core'
verbosity = int(options.get('verbosity', 1))
interactive = options.get('interactive', True)
failfast = options.get('failfast', False)
TestRunner = self.get_runner()
if not inspect.ismethod(TestRunner):
our_options = {"verbosity" : int(verbosity), "interactive" : interactive, "failfast" : failfast}
options.update(our_options)
failures = TestRunner(test_labels, **options)
else:
test_runner = TestRunner(verbosity=verbosity, interactive=interactive, failfast=failfast)
failures = test_runner.run_tests(test_labels)
if failures:
sys.exit(bool(failures))
class PycharmTestManagementUtility(ManagementUtility):
def __init__(self, argv=None):
ManagementUtility.__init__(self, argv)
def execute(self):
if is_nosetest(settings) and "_JB_USE_OLD_RUNNERS" not in os.environ:
# New way to run django-nose is to install teamcity-runners plugin
# there is no easy way to get qname in 2.7 so string is used
name = "teamcity.nose_report.TeamcityReport"
# emulate TC to enable plugin
os.environ.update({teamcity_presence_env_var: "1"})
# NOSE_PLUGINS could be list or tuple. Adding teamcity plugin to it
try:
settings.NOSE_PLUGINS += [name]
except TypeError:
settings.NOSE_PLUGINS += (name, )
except AttributeError:
settings.NOSE_PLUGINS = [name]
# This file is required to init and monkeypatch new runners
# noinspection PyUnresolvedReferences
import _jb_runner_tools
super(PycharmTestManagementUtility, self).execute()
else:
PycharmTestCommand().run_from_argv(self.argv)
if __name__ == "__main__":
try:
custom_settings = __import__(settings_file)
splitted_settings = settings_file.split('.')
if len(splitted_settings) != 1:
settings_name = '.'.join(splitted_settings[:-1])
settings_module = __import__(settings_name, globals(), locals(), [splitted_settings[-1]])
custom_settings = getattr(settings_module, splitted_settings[-1])
except ImportError:
print ("There is no such settings file " + str(settings_file) + "\n")
try:
subcommand = sys.argv[1]
except IndexError:
subcommand = 'help' # Display help if no arguments were given.
if subcommand == 'test':
utility = PycharmTestManagementUtility(sys.argv)
else:
utility = ManagementUtility()
utility.execute()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment