mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Refs #32552 -- Added DiscoverRunner.log() to allow customization.
Thanks Carlton Gibson, Chris Jerdonek, and David Smith for reviews.
This commit is contained in:
parent
cd19db10df
commit
a0410ffe8f
@ -581,6 +581,19 @@ class DiscoverRunner:
|
||||
),
|
||||
)
|
||||
|
||||
def log(self, msg, level=None):
|
||||
"""
|
||||
Log the given message at the given logging level.
|
||||
|
||||
A verbosity of 1 logs INFO (the default level) or above, and verbosity
|
||||
2 or higher logs all levels.
|
||||
"""
|
||||
if self.verbosity <= 0 or (
|
||||
self.verbosity == 1 and level is not None and level < logging.INFO
|
||||
):
|
||||
return
|
||||
print(msg)
|
||||
|
||||
def setup_test_environment(self, **kwargs):
|
||||
setup_test_environment(debug=self.debug_mode)
|
||||
unittest.installHandler()
|
||||
@ -639,11 +652,16 @@ class DiscoverRunner:
|
||||
all_tests.extend(iter_test_cases(extra_tests))
|
||||
|
||||
if self.tags or self.exclude_tags:
|
||||
if self.verbosity >= 2:
|
||||
if self.tags:
|
||||
print('Including test tag(s): %s.' % ', '.join(sorted(self.tags)))
|
||||
self.log(
|
||||
'Including test tag(s): %s.' % ', '.join(sorted(self.tags)),
|
||||
level=logging.DEBUG,
|
||||
)
|
||||
if self.exclude_tags:
|
||||
print('Excluding test tag(s): %s.' % ', '.join(sorted(self.exclude_tags)))
|
||||
self.log(
|
||||
'Excluding test tag(s): %s.' % ', '.join(sorted(self.exclude_tags)),
|
||||
level=logging.DEBUG,
|
||||
)
|
||||
all_tests = filter_tests_by_tags(all_tests, self.tags, self.exclude_tags)
|
||||
|
||||
# Put the failures detected at load time first for quicker feedback.
|
||||
@ -651,8 +669,7 @@ class DiscoverRunner:
|
||||
# found or that couldn't be loaded due to syntax errors.
|
||||
test_types = (unittest.loader._FailedTest, *self.reorder_by)
|
||||
all_tests = list(reorder_tests(all_tests, test_types, self.reverse))
|
||||
if self.verbosity >= 1:
|
||||
print('Found %d tests.' % len(all_tests))
|
||||
self.log('Found %d tests.' % len(all_tests), level=logging.INFO)
|
||||
suite = self.test_suite(all_tests)
|
||||
|
||||
if self.parallel > 1:
|
||||
@ -736,10 +753,12 @@ class DiscoverRunner:
|
||||
|
||||
def get_databases(self, suite):
|
||||
databases = self._get_databases(suite)
|
||||
if self.verbosity >= 2:
|
||||
unused_databases = [alias for alias in connections if alias not in databases]
|
||||
if unused_databases:
|
||||
print('Skipping setup of unused database(s): %s.' % ', '.join(sorted(unused_databases)))
|
||||
self.log(
|
||||
'Skipping setup of unused database(s): %s.' % ', '.join(sorted(unused_databases)),
|
||||
level=logging.DEBUG,
|
||||
)
|
||||
return databases
|
||||
|
||||
def run_tests(self, test_labels, extra_tests=None, **kwargs):
|
||||
|
@ -294,6 +294,9 @@ Tests
|
||||
* Django test runner now supports a :option:`--buffer <test --buffer>` option
|
||||
with parallel tests.
|
||||
|
||||
* The new :meth:`.DiscoverRunner.log` method allows customizing the way
|
||||
messages are logged.
|
||||
|
||||
URLs
|
||||
~~~~
|
||||
|
||||
|
@ -705,6 +705,17 @@ Methods
|
||||
Computes and returns a return code based on a test suite, and the result
|
||||
from that test suite.
|
||||
|
||||
.. method:: DiscoverRunner.log(msg, level=None)
|
||||
|
||||
.. versionadded:: 4.0
|
||||
|
||||
Prints to the console a message with the given integer `logging level`_
|
||||
(e.g. ``logging.DEBUG``, ``logging.INFO``, or ``logging.WARNING``),
|
||||
respecting the current ``verbosity``. For example, an ``INFO`` message will
|
||||
be logged if the ``verbosity`` is at least 1, and ``DEBUG`` will be logged
|
||||
if it is at least 2.
|
||||
|
||||
.. _`logging level`: https://docs.python.org/3/library/logging.html#levels
|
||||
|
||||
Testing utilities
|
||||
-----------------
|
||||
|
@ -1,3 +1,4 @@
|
||||
import logging
|
||||
import os
|
||||
import unittest.loader
|
||||
from argparse import ArgumentParser
|
||||
@ -378,6 +379,43 @@ class DiscoverRunnerTests(SimpleTestCase):
|
||||
self.assertTrue(isinstance(runner.time_keeper, TimeKeeper))
|
||||
self.assertIn('test', stderr.getvalue())
|
||||
|
||||
def test_log(self):
|
||||
custom_low_level = 5
|
||||
custom_high_level = 45
|
||||
msg = 'logging message'
|
||||
cases = [
|
||||
(0, None, False),
|
||||
(0, custom_low_level, False),
|
||||
(0, logging.DEBUG, False),
|
||||
(0, logging.INFO, False),
|
||||
(0, logging.WARNING, False),
|
||||
(0, custom_high_level, False),
|
||||
(1, None, True),
|
||||
(1, custom_low_level, False),
|
||||
(1, logging.DEBUG, False),
|
||||
(1, logging.INFO, True),
|
||||
(1, logging.WARNING, True),
|
||||
(1, custom_high_level, True),
|
||||
(2, None, True),
|
||||
(2, custom_low_level, True),
|
||||
(2, logging.DEBUG, True),
|
||||
(2, logging.INFO, True),
|
||||
(2, logging.WARNING, True),
|
||||
(2, custom_high_level, True),
|
||||
(3, None, True),
|
||||
(3, custom_low_level, True),
|
||||
(3, logging.DEBUG, True),
|
||||
(3, logging.INFO, True),
|
||||
(3, logging.WARNING, True),
|
||||
(3, custom_high_level, True),
|
||||
]
|
||||
for verbosity, level, output in cases:
|
||||
with self.subTest(verbosity=verbosity, level=level):
|
||||
with captured_stdout() as stdout:
|
||||
runner = DiscoverRunner(verbosity=verbosity)
|
||||
runner.log(msg, level)
|
||||
self.assertEqual(stdout.getvalue(), f'{msg}\n' if output else '')
|
||||
|
||||
|
||||
class DiscoverRunnerGetDatabasesTests(SimpleTestCase):
|
||||
runner = DiscoverRunner(verbosity=2)
|
||||
|
Loading…
Reference in New Issue
Block a user