mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-18 00:20:54 +07:00
Remove the 'extra_tests' argument if a Django version >= 4.0 Merge-request: IJ-MR-120964 Merged-by: Egor Eliseev <Egor.Eliseev@jetbrains.com> GitOrigin-RevId: d9274d828827112a01fd04d0ea62f4df945772af
259 lines
8.2 KiB
Python
259 lines
8.2 KiB
Python
from tcunittest import TeamcityTestRunner, TeamcityTestResult
|
|
from tcmessages import TeamcityServiceMessages
|
|
import sys
|
|
from pycharm_run_utils import adjust_django_sys_path
|
|
from django.test.utils import get_runner
|
|
|
|
adjust_django_sys_path()
|
|
|
|
from django.conf import settings
|
|
|
|
def is_nosetest(settings):
|
|
"""
|
|
Checks if Django configured to work with nosetest
|
|
|
|
:param settings: django settings
|
|
:return: True if django should works with NoseTest runner of its inheritor
|
|
"""
|
|
try:
|
|
runner = get_runner(settings)
|
|
from django_nose import NoseTestSuiteRunner
|
|
if issubclass(runner, NoseTestSuiteRunner):
|
|
return True
|
|
except (AttributeError, ImportError):
|
|
pass
|
|
return False
|
|
|
|
|
|
from django.test.testcases import TestCase
|
|
from django import VERSION
|
|
|
|
if is_nosetest(settings):
|
|
from nose_utils import TeamcityNoseRunner
|
|
|
|
# See: https://docs.djangoproject.com/en/1.8/releases/1.7/#django-utils-unittest
|
|
# django.utils.unittest provided uniform access to the unittest2 library on all Python versions.
|
|
# Since unittest2 became the standard library's unittest module in Python 2.7,
|
|
# and Django 1.7 drops support for older Python versions, this module isn't useful anymore.
|
|
# It has been deprecated. Use unittest instead.
|
|
if VERSION >= (1,7):
|
|
import unittest
|
|
else:
|
|
from django.utils import unittest
|
|
|
|
def get_test_suite_runner():
|
|
if hasattr(settings, "TEST_RUNNER"):
|
|
from django.test.utils import get_runner
|
|
|
|
class TempSettings:
|
|
TEST_RUNNER = settings.TEST_RUNNER
|
|
|
|
return get_runner(TempSettings)
|
|
|
|
try:
|
|
if VERSION >= (1,6):
|
|
from django.test.runner import DiscoverRunner as DjangoSuiteRunner
|
|
else:
|
|
from django.test.simple import DjangoTestSuiteRunner as DjangoSuiteRunner
|
|
|
|
from inspect import isfunction
|
|
|
|
SUITE_RUNNER = get_test_suite_runner()
|
|
if isfunction(SUITE_RUNNER):
|
|
import sys
|
|
|
|
sys.stderr.write(
|
|
"WARNING: TEST_RUNNER variable is ignored. PyCharm test runner supports "
|
|
"only class-like TEST_RUNNER valiables. Use Tools->run manage.py tasks.\n")
|
|
SUITE_RUNNER = None
|
|
BaseSuiteRunner = SUITE_RUNNER or DjangoSuiteRunner
|
|
|
|
class BaseRunner(TeamcityTestRunner, BaseSuiteRunner):
|
|
def __init__(self, stream=sys.stdout, **options):
|
|
TeamcityTestRunner.__init__(self, stream)
|
|
BaseSuiteRunner.__init__(self, **options)
|
|
|
|
except ImportError:
|
|
# for Django <= 1.1 compatibility
|
|
class BaseRunner(TeamcityTestRunner):
|
|
def __init__(self, stream=sys.stdout, **options):
|
|
TeamcityTestRunner.__init__(self, stream)
|
|
|
|
IS_EXTRA_TESTS_ARG_DEPRECATED = True if VERSION >= (4, ) else False
|
|
|
|
|
|
def strclass(cls):
|
|
if not cls.__name__:
|
|
return cls.__module__
|
|
return "%s.%s" % (cls.__module__, cls.__name__)
|
|
|
|
class DjangoTeamcityTestResult(TeamcityTestResult):
|
|
def __init__(self, *args, **kwargs):
|
|
super(DjangoTeamcityTestResult, self).__init__(**kwargs)
|
|
|
|
def _getSuite(self, test):
|
|
if hasattr(test, "suite"):
|
|
suite = strclass(test.suite)
|
|
suite_location = test.suite.location
|
|
location = test.suite.abs_location
|
|
if hasattr(test, "lineno"):
|
|
location = location + ":" + str(test.lineno)
|
|
else:
|
|
location = location + ":" + str(test.test.lineno)
|
|
else:
|
|
|
|
suite = strclass(test.__class__)
|
|
suite_location = "django_testid://" + suite
|
|
location = "django_testid://" + str(test.id())
|
|
|
|
return (suite, location, suite_location)
|
|
|
|
|
|
class DjangoTeamcityTestRunner(BaseRunner):
|
|
def __init__(self, stream=sys.stdout, **options):
|
|
super(DjangoTeamcityTestRunner, self).__init__(stream, **options)
|
|
self.options = options
|
|
|
|
def _makeResult(self, **kwargs):
|
|
return DjangoTeamcityTestResult(self.stream, **kwargs)
|
|
|
|
def build_suite(self, *args, **kwargs):
|
|
EXCLUDED_APPS = getattr(settings, 'TEST_EXCLUDE', [])
|
|
suite = super(DjangoTeamcityTestRunner, self).build_suite(*args, **kwargs)
|
|
if not args[0] and not getattr(settings, 'RUN_ALL_TESTS', False):
|
|
tests = []
|
|
for case in suite:
|
|
pkg = case.__class__.__module__.split('.')[0]
|
|
if pkg not in EXCLUDED_APPS:
|
|
tests.append(case)
|
|
suite._tests = tests
|
|
return suite
|
|
|
|
def run_suite(self, suite, **kwargs):
|
|
if is_nosetest(settings):
|
|
from django_nose.plugin import DjangoSetUpPlugin, ResultPlugin
|
|
from django_nose.runner import _get_plugins_from_settings
|
|
from nose.config import Config
|
|
import nose
|
|
|
|
result_plugin = ResultPlugin()
|
|
plugins_to_add = [DjangoSetUpPlugin(self), result_plugin]
|
|
|
|
config = Config(plugins=nose.core.DefaultPluginManager())
|
|
config.plugins.addPlugins(extraplugins=plugins_to_add)
|
|
|
|
for plugin in _get_plugins_from_settings():
|
|
plugins_to_add.append(plugin)
|
|
nose.core.TestProgram(argv=suite, exit=False, addplugins=plugins_to_add,
|
|
testRunner=TeamcityNoseRunner(config=config))
|
|
return result_plugin.result
|
|
|
|
else:
|
|
self.options.update(kwargs)
|
|
return TeamcityTestRunner.run(self, suite, **self.options)
|
|
|
|
def run_tests(self, test_labels, extra_tests=None, **kwargs):
|
|
args = (test_labels, ) if IS_EXTRA_TESTS_ARG_DEPRECATED else (test_labels, extra_tests)
|
|
|
|
if is_nosetest(settings):
|
|
return super(DjangoTeamcityTestRunner, self).run_tests(*args)
|
|
return super(DjangoTeamcityTestRunner, self).run_tests(*args, **kwargs)
|
|
|
|
|
|
def partition_suite(suite, classes, bins):
|
|
"""
|
|
Partitions a test suite by test type.
|
|
|
|
classes is a sequence of types
|
|
bins is a sequence of TestSuites, one more than classes
|
|
|
|
Tests of type classes[i] are added to bins[i],
|
|
tests with no match found in classes are place in bins[-1]
|
|
"""
|
|
for test in suite:
|
|
if isinstance(test, unittest.TestSuite):
|
|
partition_suite(test, classes, bins)
|
|
else:
|
|
for i in range(len(classes)):
|
|
if isinstance(test, classes[i]):
|
|
bins[i].addTest(test)
|
|
break
|
|
else:
|
|
bins[-1].addTest(test)
|
|
|
|
|
|
def reorder_suite(suite, classes):
|
|
"""
|
|
Reorders a test suite by test type.
|
|
|
|
classes is a sequence of types
|
|
|
|
All tests of type clases[0] are placed first, then tests of type classes[1], etc.
|
|
Tests with no match in classes are placed last.
|
|
"""
|
|
class_count = len(classes)
|
|
bins = [unittest.TestSuite() for i in range(class_count + 1)]
|
|
partition_suite(suite, classes, bins)
|
|
for i in range(class_count):
|
|
bins[0].addTests(bins[i + 1])
|
|
return bins[0]
|
|
|
|
|
|
def run_the_old_way(extra_tests, kwargs, test_labels, verbosity):
|
|
from django.test.simple import build_suite, build_test, get_app, get_apps, \
|
|
setup_test_environment, teardown_test_environment
|
|
|
|
setup_test_environment()
|
|
settings.DEBUG = False
|
|
suite = unittest.TestSuite()
|
|
if test_labels:
|
|
for label in test_labels:
|
|
if '.' in label:
|
|
suite.addTest(build_test(label))
|
|
else:
|
|
app = get_app(label)
|
|
suite.addTest(build_suite(app))
|
|
else:
|
|
for app in get_apps():
|
|
suite.addTest(build_suite(app))
|
|
for test in extra_tests:
|
|
suite.addTest(test)
|
|
suite = reorder_suite(suite, (TestCase,))
|
|
old_name = settings.DATABASE_NAME
|
|
from django.db import connection
|
|
|
|
connection.creation.create_test_db(verbosity, autoclobber=False)
|
|
result = DjangoTeamcityTestRunner().run(suite, **kwargs)
|
|
connection.creation.destroy_test_db(old_name, verbosity)
|
|
teardown_test_environment()
|
|
return len(result.failures) + len(result.errors)
|
|
|
|
|
|
def run_tests(test_labels, verbosity=1, interactive=False, extra_tests=[],
|
|
**kwargs):
|
|
"""
|
|
Run the unit tests for all the test labels in the provided list.
|
|
Labels must be of the form:
|
|
- app.TestClass.test_method
|
|
Run a single specific test method
|
|
- app.TestClass
|
|
Run all the test methods in a given class
|
|
- app
|
|
Search for doctests and unittests in the named application.
|
|
|
|
When looking for tests, the test runner will look in the models and
|
|
tests modules for the application.
|
|
|
|
A list of 'extra' tests may also be provided; these tests
|
|
will be added to the test suite.
|
|
|
|
Returns the number of tests that failed.
|
|
"""
|
|
options = {
|
|
'verbosity': verbosity,
|
|
'interactive': interactive
|
|
}
|
|
options.update(kwargs)
|
|
TeamcityServiceMessages(sys.stdout).testMatrixEntered()
|
|
return DjangoTeamcityTestRunner(**options).run_tests(test_labels,
|
|
extra_tests=extra_tests, **options) |