mirror of https://github.com/django/django.git
Fixed #33264 -- Made test runner return non-zero error code for unexpected successes.
This commit is contained in:
parent
1a5023883b
commit
91acfc3514
|
@ -875,7 +875,7 @@ class DiscoverRunner:
|
||||||
teardown_test_environment()
|
teardown_test_environment()
|
||||||
|
|
||||||
def suite_result(self, suite, result, **kwargs):
|
def suite_result(self, suite, result, **kwargs):
|
||||||
return len(result.failures) + len(result.errors)
|
return len(result.failures) + len(result.errors) + len(result.unexpectedSuccesses)
|
||||||
|
|
||||||
def _get_databases(self, suite):
|
def _get_databases(self, suite):
|
||||||
databases = {}
|
databases = {}
|
||||||
|
|
|
@ -260,6 +260,9 @@ Miscellaneous
|
||||||
:class:`~django.contrib.contenttypes.fields.GenericRelation` are now cached
|
:class:`~django.contrib.contenttypes.fields.GenericRelation` are now cached
|
||||||
on the :class:`~django.db.models.Model` instance to which they belong.
|
on the :class:`~django.db.models.Model` instance to which they belong.
|
||||||
|
|
||||||
|
* The Django test runner now returns a non-zero error code for unexpected
|
||||||
|
successes from tests marked with :py:func:`unittest.expectedFailure`.
|
||||||
|
|
||||||
.. _deprecated-features-4.1:
|
.. _deprecated-features-4.1:
|
||||||
|
|
||||||
Features deprecated in 4.1
|
Features deprecated in 4.1
|
||||||
|
|
|
@ -331,10 +331,15 @@ but it's pretty intuitive. You can consult the documentation of Python's
|
||||||
:mod:`unittest` library for details.
|
:mod:`unittest` library for details.
|
||||||
|
|
||||||
Note that the return code for the test-runner script is 1 for any number of
|
Note that the return code for the test-runner script is 1 for any number of
|
||||||
failed and erroneous tests. If all the tests pass, the return code is 0. This
|
failed tests (whether the failure was caused by an error, a failed assertion,
|
||||||
|
or an unexpected success). If all the tests pass, the return code is 0. This
|
||||||
feature is useful if you're using the test-runner script in a shell script and
|
feature is useful if you're using the test-runner script in a shell script and
|
||||||
need to test for success or failure at that level.
|
need to test for success or failure at that level.
|
||||||
|
|
||||||
|
.. versionchanged:: 4.1
|
||||||
|
|
||||||
|
In older versions, the return code was 0 for unexpected successes.
|
||||||
|
|
||||||
.. _speeding-up-tests-auth-hashers:
|
.. _speeding-up-tests-auth-hashers:
|
||||||
|
|
||||||
Speeding up the tests
|
Speeding up the tests
|
||||||
|
|
|
@ -644,6 +644,24 @@ class DiscoverRunnerTests(SimpleTestCase):
|
||||||
runner.log('log message', level)
|
runner.log('log message', level)
|
||||||
self.assertEqual(cm.output, [expected])
|
self.assertEqual(cm.output, [expected])
|
||||||
|
|
||||||
|
def test_suite_result_with_failure(self):
|
||||||
|
cases = [
|
||||||
|
(1, 'FailureTestCase'),
|
||||||
|
(1, 'ErrorTestCase'),
|
||||||
|
(0, 'ExpectedFailureTestCase'),
|
||||||
|
(1, 'UnexpectedSuccessTestCase'),
|
||||||
|
]
|
||||||
|
runner = DiscoverRunner(verbosity=0)
|
||||||
|
for expected_failures, testcase in cases:
|
||||||
|
with self.subTest(testcase=testcase):
|
||||||
|
suite = runner.build_suite([
|
||||||
|
f'test_runner_apps.failures.tests_failures.{testcase}',
|
||||||
|
])
|
||||||
|
with captured_stderr():
|
||||||
|
result = runner.run_suite(suite)
|
||||||
|
failures = runner.suite_result(suite, result)
|
||||||
|
self.assertEqual(failures, expected_failures)
|
||||||
|
|
||||||
|
|
||||||
class DiscoverRunnerGetDatabasesTests(SimpleTestCase):
|
class DiscoverRunnerGetDatabasesTests(SimpleTestCase):
|
||||||
runner = DiscoverRunner(verbosity=2)
|
runner = DiscoverRunner(verbosity=2)
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
from unittest import TestCase, expectedFailure
|
||||||
|
|
||||||
|
|
||||||
|
class FailureTestCase(TestCase):
|
||||||
|
def test_sample(self):
|
||||||
|
self.assertEqual(0, 1)
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorTestCase(TestCase):
|
||||||
|
def test_sample(self):
|
||||||
|
raise Exception('test')
|
||||||
|
|
||||||
|
|
||||||
|
class ExpectedFailureTestCase(TestCase):
|
||||||
|
@expectedFailure
|
||||||
|
def test_sample(self):
|
||||||
|
self.assertEqual(0, 1)
|
||||||
|
|
||||||
|
|
||||||
|
class UnexpectedSuccessTestCase(TestCase):
|
||||||
|
@expectedFailure
|
||||||
|
def test_sample(self):
|
||||||
|
self.assertEqual(1, 1)
|
Loading…
Reference in New Issue