Created
July 25, 2017 17:57
-
-
Save IuryAlves/61b0a4b8723b868604168b9e6292d1a1 to your computer and use it in GitHub Desktop.
Run Django tests without migrations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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