Fixed #29127 -- Prevented DiscoverRunner from hiding tagged test with syntax errors.

This mades _FailedTest objects always match tags in DiscoverRunner.
This commit is contained in:
Chris Jerdonek 2021-03-26 05:14:43 -07:00 committed by Mariusz Felisiak
parent 7c08f26bf0
commit 038940cf55
5 changed files with 37 additions and 0 deletions

View File

@ -852,6 +852,10 @@ def partition_suite_by_case(suite):
def test_match_tags(test, tags, exclude_tags): def test_match_tags(test, tags, exclude_tags):
if isinstance(test, unittest.loader._FailedTest):
# Tests that couldn't load always match to prevent tests from falsely
# passing due e.g. to syntax errors.
return True
test_tags = set(getattr(test, 'tags', [])) test_tags = set(getattr(test, 'tags', []))
test_fn_name = getattr(test, '_testMethodName', str(test)) test_fn_name = getattr(test, '_testMethodName', str(test))
if hasattr(test, test_fn_name): if hasattr(test, test_fn_name):

View File

@ -1497,6 +1497,12 @@ don't.
Runs only tests :ref:`marked with the specified tags <topics-tagging-tests>`. Runs only tests :ref:`marked with the specified tags <topics-tagging-tests>`.
May be specified multiple times and combined with :option:`test --exclude-tag`. May be specified multiple times and combined with :option:`test --exclude-tag`.
Tests that fail to load are always considered matching.
.. versionchanged:: 4.0
In older versions, tests that failed to load did not match tags.
.. option:: --exclude-tag EXCLUDE_TAGS .. option:: --exclude-tag EXCLUDE_TAGS
Excludes tests :ref:`marked with the specified tags <topics-tagging-tests>`. Excludes tests :ref:`marked with the specified tags <topics-tagging-tests>`.

View File

@ -373,6 +373,9 @@ Miscellaneous
non-boolean attribute without a value equal to an attribute with the same non-boolean attribute without a value equal to an attribute with the same
name and value. name and value.
* Tests that fail to load, for example due to syntax errors, now always match
when using :option:`test --tag`.
.. _deprecated-features-4.0: .. _deprecated-features-4.0:
Features deprecated in 4.0 Features deprecated in 4.0

View File

@ -2,6 +2,7 @@ import os
import unittest.loader import unittest.loader
from argparse import ArgumentParser from argparse import ArgumentParser
from contextlib import contextmanager from contextlib import contextmanager
from importlib import import_module
from unittest import TestSuite, TextTestRunner, defaultTestLoader, mock from unittest import TestSuite, TextTestRunner, defaultTestLoader, mock
from django.db import connections from django.db import connections
@ -259,6 +260,18 @@ class DiscoverRunnerTests(SimpleTestCase):
self.assertEqual(count_tests(tags=['foo'], exclude_tags=['bar', 'baz']), 1) self.assertEqual(count_tests(tags=['foo'], exclude_tags=['bar', 'baz']), 1)
self.assertEqual(count_tests(exclude_tags=['foo']), 0) self.assertEqual(count_tests(exclude_tags=['foo']), 0)
def test_tag_fail_to_load(self):
with self.assertRaises(SyntaxError):
import_module('test_runner_apps.tagged.tests_syntax_error')
runner = DiscoverRunner(tags=['syntax_error'])
# A label that doesn't exist or cannot be loaded due to syntax errors
# is always considered matching.
suite = runner.build_suite(['doesnotexist', 'test_runner_apps.tagged'])
self.assertEqual([test.id() for test in suite], [
'unittest.loader._FailedTest.doesnotexist',
'unittest.loader._FailedTest.test_runner_apps.tagged.tests_syntax_error',
])
def test_included_tags_displayed(self): def test_included_tags_displayed(self):
runner = DiscoverRunner(tags=['foo', 'bar'], verbosity=2) runner = DiscoverRunner(tags=['foo', 'bar'], verbosity=2)
with captured_stdout() as stdout: with captured_stdout() as stdout:

View File

@ -0,0 +1,11 @@
from unittest import TestCase
from django.test import tag
@tag('syntax_error')
class SyntaxErrorTestCase(TestCase):
pass
1syntax_error # NOQA