summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniyal <abbasi.daniyal98@gmail.com>2021-03-19 14:50:08 +0530
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-06-01 13:31:44 +0200
commita0410ffe8f43d8dcfbaa261e068879698fafdca3 (patch)
tree61365ebcb837198310827c7129af9cea9257a636
parentcd19db10df6225e01b77685397a88c9cdf216dd1 (diff)
Refs #32552 -- Added DiscoverRunner.log() to allow customization.
Thanks Carlton Gibson, Chris Jerdonek, and David Smith for reviews.
-rw-r--r--django/test/runner.py41
-rw-r--r--docs/releases/4.0.txt3
-rw-r--r--docs/topics/testing/advanced.txt11
-rw-r--r--tests/test_runner/test_discover_runner.py38
4 files changed, 82 insertions, 11 deletions
diff --git a/django/test/runner.py b/django/test/runner.py
index ab5512e628..dea3703d89 100644
--- a/django/test/runner.py
+++ b/django/test/runner.py
@@ -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)))
- if self.exclude_tags:
- print('Excluding test tag(s): %s.' % ', '.join(sorted(self.exclude_tags)))
+ if self.tags:
+ self.log(
+ 'Including test tag(s): %s.' % ', '.join(sorted(self.tags)),
+ level=logging.DEBUG,
+ )
+ if 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)))
+ unused_databases = [alias for alias in connections if alias not in databases]
+ if 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):
diff --git a/docs/releases/4.0.txt b/docs/releases/4.0.txt
index 7695ce95a2..60c449bc88 100644
--- a/docs/releases/4.0.txt
+++ b/docs/releases/4.0.txt
@@ -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
~~~~
diff --git a/docs/topics/testing/advanced.txt b/docs/topics/testing/advanced.txt
index d3903757f6..a8a63e7b57 100644
--- a/docs/topics/testing/advanced.txt
+++ b/docs/topics/testing/advanced.txt
@@ -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
-----------------
diff --git a/tests/test_runner/test_discover_runner.py b/tests/test_runner/test_discover_runner.py
index 8f360292f1..d4ec6e97e1 100644
--- a/tests/test_runner/test_discover_runner.py
+++ b/tests/test_runner/test_discover_runner.py
@@ -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)