bpo-45162: Remove many old deprecated unittest features (GH-28268)

* "fail*" and "assert*" aliases of TestCase methods.
* Broken from start TestCase method assertDictContainsSubset().
* Ignored TestLoader.loadTestsFromModule() parameter use_load_tests.
* Old alias _TextTestResult of TextTestResult.
This commit is contained in:
Serhiy Storchaka 2021-09-17 13:33:27 +03:00 committed by GitHub
parent 0361335b80
commit b0a6ede3d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 61 additions and 373 deletions

View file

@ -1237,9 +1237,6 @@ Test cases
:meth:`.assertRegex`. :meth:`.assertRegex`.
.. versionadded:: 3.2 .. versionadded:: 3.2
:meth:`.assertNotRegex`. :meth:`.assertNotRegex`.
.. versionadded:: 3.5
The name ``assertNotRegexpMatches`` is a deprecated alias
for :meth:`.assertNotRegex`.
.. method:: assertCountEqual(first, second, msg=None) .. method:: assertCountEqual(first, second, msg=None)
@ -1605,40 +1602,6 @@ Test cases
:mod:`unittest`-based test framework. :mod:`unittest`-based test framework.
.. _deprecated-aliases:
Deprecated aliases
##################
For historical reasons, some of the :class:`TestCase` methods had one or more
aliases that are now deprecated. The following table lists the correct names
along with their deprecated aliases:
============================== ====================== =======================
Method Name Deprecated alias Deprecated alias
============================== ====================== =======================
:meth:`.assertEqual` failUnlessEqual assertEquals
:meth:`.assertNotEqual` failIfEqual assertNotEquals
:meth:`.assertTrue` failUnless assert\_
:meth:`.assertFalse` failIf
:meth:`.assertRaises` failUnlessRaises
:meth:`.assertAlmostEqual` failUnlessAlmostEqual assertAlmostEquals
:meth:`.assertNotAlmostEqual` failIfAlmostEqual assertNotAlmostEquals
:meth:`.assertRegex` assertRegexpMatches
:meth:`.assertNotRegex` assertNotRegexpMatches
:meth:`.assertRaisesRegex` assertRaisesRegexp
============================== ====================== =======================
.. deprecated:: 3.1
The fail* aliases listed in the second column have been deprecated.
.. deprecated:: 3.2
The assert* aliases listed in the third column have been deprecated.
.. deprecated:: 3.2
``assertRegexpMatches`` and ``assertRaisesRegexp`` have been renamed to
:meth:`.assertRegex` and :meth:`.assertRaisesRegex`.
.. deprecated:: 3.5
The ``assertNotRegexpMatches`` name is deprecated in favor of :meth:`.assertNotRegex`.
.. _testsuite-objects: .. _testsuite-objects:
Grouping tests Grouping tests
@ -1764,7 +1727,7 @@ Loading and running tests
case is created for that method instead. case is created for that method instead.
.. method:: loadTestsFromModule(module, pattern=None) .. method:: loadTestsFromModule(module, *, pattern=None)
Return a suite of all test cases contained in the given module. This Return a suite of all test cases contained in the given module. This
method searches *module* for classes derived from :class:`TestCase` and method searches *module* for classes derived from :class:`TestCase` and
@ -1788,10 +1751,11 @@ Loading and running tests
Support for ``load_tests`` added. Support for ``load_tests`` added.
.. versionchanged:: 3.5 .. versionchanged:: 3.5
The undocumented and unofficial *use_load_tests* default argument is Support for a keyword-only argument *pattern* has been added.
deprecated and ignored, although it is still accepted for backward
compatibility. The method also now accepts a keyword-only argument .. versionchanged:: 3.11
*pattern* which is passed to ``load_tests`` as the third argument. The undocumented and unofficial *use_load_tests* parameter has been
removed.
.. method:: loadTestsFromName(name, module=None) .. method:: loadTestsFromName(name, module=None)
@ -2144,8 +2108,6 @@ Loading and running tests
:class:`TextTestRunner`. :class:`TextTestRunner`.
.. versionadded:: 3.2 .. versionadded:: 3.2
This class was previously named ``_TextTestResult``. The old name still
exists as an alias but is deprecated.
.. data:: defaultTestLoader .. data:: defaultTestLoader
@ -2168,10 +2130,7 @@ Loading and running tests
By default this runner shows :exc:`DeprecationWarning`, By default this runner shows :exc:`DeprecationWarning`,
:exc:`PendingDeprecationWarning`, :exc:`ResourceWarning` and :exc:`PendingDeprecationWarning`, :exc:`ResourceWarning` and
:exc:`ImportWarning` even if they are :ref:`ignored by default :exc:`ImportWarning` even if they are :ref:`ignored by default
<warning-ignored>`. Deprecation warnings caused by :ref:`deprecated unittest <warning-ignored>`. This behavior can
methods <deprecated-aliases>` are also special-cased and, when the warning
filters are ``'default'`` or ``'always'``, they will appear only once
per-module, in order to avoid too many warning messages. This behavior can
be overridden using Python's :option:`!-Wd` or :option:`!-Wa` options be overridden using Python's :option:`!-Wd` or :option:`!-Wa` options
(see :ref:`Warning control <using-on-warnings>`) and leaving (see :ref:`Warning control <using-on-warnings>`) and leaving
*warnings* to ``None``. *warnings* to ``None``.

View file

@ -277,6 +277,28 @@ Removed
and :class:`fileinput.FileInput`, deprecated since Python 3.9. and :class:`fileinput.FileInput`, deprecated since Python 3.9.
(Contributed by Hugo van Kemenade in :issue:`45132`.) (Contributed by Hugo van Kemenade in :issue:`45132`.)
* Removed many old deprecated :mod:`unittest` features:
- :class:`~unittest.TestCase` method aliases ``failUnlessEqual``,
``failIfEqual``, ``failUnless``, ``failIf``, ``failUnlessRaises``,
``failUnlessAlmostEqual``, ``failIfAlmostEqual`` (deprecated in Python 3.1),
``assertEquals``, ``assertNotEquals``, ``assert_``, ``assertAlmostEquals``,
``assertNotAlmostEquals``, ``assertRegexpMatches``, ``assertRaisesRegexp``
(deprecated in Python 3.2), and ``assertNotRegexpMatches`` (deprecated in
Python 3.5).
- Undocumented and broken :class:`~unittest.TestCase` method
``assertDictContainsSubset`` (deprecated in Python 3.2).
- Undocumented :meth:`<unittest.TestLoader.loadTestsFromModule>
TestLoader.loadTestsFromModule` parameter *use_load_tests* (deprecated
and ignored since Python 3.2).
- An alias of the :class:`~unittest.TextTestResult` class:
``_TextTestResult`` (deprecated in Python 3.2).
(Contributed by Serhiy Storchaka in :issue:`45162`.)
* The following deprecated functions and methods are removed in the :mod:`gettext` * The following deprecated functions and methods are removed in the :mod:`gettext`
module: :func:`~gettext.lgettext`, :func:`~gettext.ldgettext`, module: :func:`~gettext.lgettext`, :func:`~gettext.ldgettext`,
:func:`~gettext.lngettext` and :func:`~gettext.ldngettext`. :func:`~gettext.lngettext` and :func:`~gettext.ldngettext`.

View file

@ -1815,8 +1815,7 @@ names.
=============================== ============================== =============================== ==============================
Likewise, the ``TestCase.fail*`` methods deprecated in Python 3.1 are expected Likewise, the ``TestCase.fail*`` methods deprecated in Python 3.1 are expected
to be removed in Python 3.3. Also see the :ref:`deprecated-aliases` section in to be removed in Python 3.3.
the :mod:`unittest` documentation.
(Contributed by Ezio Melotti; :issue:`9424`.) (Contributed by Ezio Melotti; :issue:`9424`.)

View file

@ -68,9 +68,6 @@ from .signals import installHandler, registerResult, removeResult, removeHandler
# IsolatedAsyncioTestCase will be imported lazily. # IsolatedAsyncioTestCase will be imported lazily.
from .loader import makeSuite, getTestCaseNames, findTestCases from .loader import makeSuite, getTestCaseNames, findTestCases
# deprecated
_TextTestResult = TextTestResult
# There are no tests here, so don't try to run anything discovered from # There are no tests here, so don't try to run anything discovered from
# introspecting the symbols (e.g. FunctionTestCase). Instead, all our # introspecting the symbols (e.g. FunctionTestCase). Instead, all our

View file

@ -1137,35 +1137,6 @@ class TestCase(object):
standardMsg = self._truncateMessage(standardMsg, diff) standardMsg = self._truncateMessage(standardMsg, diff)
self.fail(self._formatMessage(msg, standardMsg)) self.fail(self._formatMessage(msg, standardMsg))
def assertDictContainsSubset(self, subset, dictionary, msg=None):
"""Checks whether dictionary is a superset of subset."""
warnings.warn('assertDictContainsSubset is deprecated',
DeprecationWarning)
missing = []
mismatched = []
for key, value in subset.items():
if key not in dictionary:
missing.append(key)
elif value != dictionary[key]:
mismatched.append('%s, expected: %s, actual: %s' %
(safe_repr(key), safe_repr(value),
safe_repr(dictionary[key])))
if not (missing or mismatched):
return
standardMsg = ''
if missing:
standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
missing)
if mismatched:
if standardMsg:
standardMsg += '; '
standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
self.fail(self._formatMessage(msg, standardMsg))
def assertCountEqual(self, first, second, msg=None): def assertCountEqual(self, first, second, msg=None):
"""Asserts that two iterables have the same elements, the same number of """Asserts that two iterables have the same elements, the same number of
times, without regard to order. times, without regard to order.
@ -1329,27 +1300,6 @@ class TestCase(object):
raise self.failureException(msg) raise self.failureException(msg)
def _deprecate(original_func):
def deprecated_func(*args, **kwargs):
warnings.warn(
'Please use {0} instead.'.format(original_func.__name__),
DeprecationWarning, 2)
return original_func(*args, **kwargs)
return deprecated_func
# see #9424
failUnlessEqual = assertEquals = _deprecate(assertEqual)
failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
failUnless = assert_ = _deprecate(assertTrue)
failUnlessRaises = _deprecate(assertRaises)
failIf = _deprecate(assertFalse)
assertRaisesRegexp = _deprecate(assertRaisesRegex)
assertRegexpMatches = _deprecate(assertRegex)
assertNotRegexpMatches = _deprecate(assertNotRegex)
class FunctionTestCase(TestCase): class FunctionTestCase(TestCase):
"""A test case that wraps a test function. """A test case that wraps a test function.

View file

@ -93,30 +93,8 @@ class TestLoader(object):
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
return loaded_suite return loaded_suite
# XXX After Python 3.5, remove backward compatibility hacks for def loadTestsFromModule(self, module, *, pattern=None):
# use_load_tests deprecation via *args and **kws. See issue 16662.
def loadTestsFromModule(self, module, *args, pattern=None, **kws):
"""Return a suite of all test cases contained in the given module""" """Return a suite of all test cases contained in the given module"""
# This method used to take an undocumented and unofficial
# use_load_tests argument. For backward compatibility, we still
# accept the argument (which can also be the first position) but we
# ignore it and issue a deprecation warning if it's present.
if len(args) > 0 or 'use_load_tests' in kws:
warnings.warn('use_load_tests is deprecated and ignored',
DeprecationWarning)
kws.pop('use_load_tests', None)
if len(args) > 1:
# Complain about the number of arguments, but don't forget the
# required `module` argument.
complaint = len(args) + 1
raise TypeError('loadTestsFromModule() takes 1 positional argument but {} were given'.format(complaint))
if len(kws) != 0:
# Since the keyword arguments are unsorted (see PEP 468), just
# pick the alphabetically sorted first argument to complain about,
# if multiple were given. At least the error message will be
# predictable.
complaint = sorted(kws)[0]
raise TypeError("loadTestsFromModule() got an unexpected keyword argument '{}'".format(complaint))
tests = [] tests = []
for name in dir(module): for name in dir(module):
obj = getattr(module, name) obj = getattr(module, name)

View file

@ -189,15 +189,6 @@ class TextTestRunner(object):
if self.warnings: if self.warnings:
# if self.warnings is set, use it to filter all the warnings # if self.warnings is set, use it to filter all the warnings
warnings.simplefilter(self.warnings) warnings.simplefilter(self.warnings)
# if the filter is 'default' or 'always', special-case the
# warnings from the deprecated unittest methods to show them
# no more than once per module, because they can be fairly
# noisy. The -Wd and -Wa flags can be used to bypass this
# only when self.warnings is None.
if self.warnings in ['default', 'always']:
warnings.filterwarnings('module',
category=DeprecationWarning,
message=r'Please use assert\w+ instead.')
startTime = time.perf_counter() startTime = time.perf_counter()
startTestRun = getattr(result, 'startTestRun', None) startTestRun = getattr(result, 'startTestRun', None)
if startTestRun is not None: if startTestRun is not None:

View file

@ -18,17 +18,6 @@ def warnfun():
warnings.warn('rw', RuntimeWarning) warnings.warn('rw', RuntimeWarning)
class TestWarnings(unittest.TestCase): class TestWarnings(unittest.TestCase):
# unittest warnings will be printed at most once per type (max one message
# for the fail* methods, and one for the assert* methods)
def test_assert(self):
self.assertEquals(2+2, 4)
self.assertEquals(2*2, 4)
self.assertEquals(2**2, 4)
def test_fail(self):
self.failUnless(1)
self.failUnless(True)
def test_other_unittest(self): def test_other_unittest(self):
self.assertAlmostEqual(2+2, 4) self.assertAlmostEqual(2+2, 4)
self.assertNotAlmostEqual(4+4, 2) self.assertNotAlmostEqual(4+4, 2)

View file

@ -271,15 +271,6 @@ class TestLongMessage(unittest.TestCase):
r"\+ \{'key': 'value'\}$", r"\+ \{'key': 'value'\}$",
r"\+ \{'key': 'value'\} : oops$"]) r"\+ \{'key': 'value'\} : oops$"])
def testAssertDictContainsSubset(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
self.assertMessages('assertDictContainsSubset', ({'key': 'value'}, {}),
["^Missing: 'key'$", "^oops$",
"^Missing: 'key'$",
"^Missing: 'key' : oops$"])
def testAssertMultiLineEqual(self): def testAssertMultiLineEqual(self):
self.assertMessages('assertMultiLineEqual', ("", "foo"), self.assertMessages('assertMultiLineEqual', ("", "foo"),
[r"\+ foo$", "^oops$", [r"\+ foo$", "^oops$",

View file

@ -696,36 +696,6 @@ class Test_TestCase(unittest.TestCase, TestEquality, TestHashing):
self.assertRaises(self.failureException, self.assertNotIn, 'cow', self.assertRaises(self.failureException, self.assertNotIn, 'cow',
animals) animals)
def testAssertDictContainsSubset(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
self.assertDictContainsSubset({}, {})
self.assertDictContainsSubset({}, {'a': 1})
self.assertDictContainsSubset({'a': 1}, {'a': 1})
self.assertDictContainsSubset({'a': 1}, {'a': 1, 'b': 2})
self.assertDictContainsSubset({'a': 1, 'b': 2}, {'a': 1, 'b': 2})
with self.assertRaises(self.failureException):
self.assertDictContainsSubset({1: "one"}, {})
with self.assertRaises(self.failureException):
self.assertDictContainsSubset({'a': 2}, {'a': 1})
with self.assertRaises(self.failureException):
self.assertDictContainsSubset({'c': 1}, {'a': 1})
with self.assertRaises(self.failureException):
self.assertDictContainsSubset({'a': 1, 'c': 1}, {'a': 1})
with self.assertRaises(self.failureException):
self.assertDictContainsSubset({'a': 1, 'c': 1}, {'a': 1})
one = ''.join(chr(i) for i in range(255))
# this used to cause a UnicodeDecodeError constructing the failure msg
with self.assertRaises(self.failureException):
self.assertDictContainsSubset({'foo': one}, {'foo': '\uFFFD'})
def testAssertEqual(self): def testAssertEqual(self):
equal_pairs = [ equal_pairs = [
((), ()), ((), ()),
@ -1788,45 +1758,18 @@ test case
pass pass
self.assertIsNone(value) self.assertIsNone(value)
def testDeprecatedMethodNames(self): def testDeprecatedFailMethods(self):
""" """Test that the deprecated fail* methods get removed in 3.11"""
Test that the deprecated methods raise a DeprecationWarning. See #9424.
"""
old = (
(self.failIfEqual, (3, 5)),
(self.assertNotEquals, (3, 5)),
(self.failUnlessEqual, (3, 3)),
(self.assertEquals, (3, 3)),
(self.failUnlessAlmostEqual, (2.0, 2.0)),
(self.assertAlmostEquals, (2.0, 2.0)),
(self.failIfAlmostEqual, (3.0, 5.0)),
(self.assertNotAlmostEquals, (3.0, 5.0)),
(self.failUnless, (True,)),
(self.assert_, (True,)),
(self.failUnlessRaises, (TypeError, lambda _: 3.14 + 'spam')),
(self.failIf, (False,)),
(self.assertDictContainsSubset, (dict(a=1, b=2), dict(a=1, b=2, c=3))),
(self.assertRaisesRegexp, (KeyError, 'foo', lambda: {}['foo'])),
(self.assertRegexpMatches, ('bar', 'bar')),
)
for meth, args in old:
with self.assertWarns(DeprecationWarning):
meth(*args)
# disable this test for now. When the version where the fail* methods will
# be removed is decided, re-enable it and update the version
def _testDeprecatedFailMethods(self):
"""Test that the deprecated fail* methods get removed in 3.x"""
if sys.version_info[:2] < (3, 3):
return
deprecated_names = [ deprecated_names = [
'failIfEqual', 'failUnlessEqual', 'failUnlessAlmostEqual', 'failIfEqual', 'failUnlessEqual', 'failUnlessAlmostEqual',
'failIfAlmostEqual', 'failUnless', 'failUnlessRaises', 'failIf', 'failIfAlmostEqual', 'failUnless', 'failUnlessRaises', 'failIf',
'assertDictContainsSubset', 'assertNotEquals', 'assertEquals', 'assertAlmostEquals',
'assertNotAlmostEquals', 'assert_', 'assertDictContainsSubset',
'assertRaisesRegexp', 'assertRegexpMatches'
] ]
for deprecated_name in deprecated_names: for deprecated_name in deprecated_names:
with self.assertRaises(AttributeError): with self.assertRaises(AttributeError):
getattr(self, deprecated_name) # remove these in 3.x getattr(self, deprecated_name)
def testDeepcopy(self): def testDeepcopy(self):
# Issue: 5660 # Issue: 5660

View file

@ -5,25 +5,6 @@ import warnings
import unittest import unittest
# Decorator used in the deprecation tests to reset the warning registry for
# test isolation and reproducibility.
def warningregistry(func):
def wrapper(*args, **kws):
missing = []
saved = getattr(warnings, '__warningregistry__', missing).copy()
try:
return func(*args, **kws)
finally:
if saved is missing:
try:
del warnings.__warningregistry__
except AttributeError:
pass
else:
warnings.__warningregistry__ = saved
return wrapper
class Test_TestLoader(unittest.TestCase): class Test_TestLoader(unittest.TestCase):
### Basic object tests ### Basic object tests
@ -174,9 +155,8 @@ class Test_TestLoader(unittest.TestCase):
self.assertEqual(list(suite), reference) self.assertEqual(list(suite), reference)
# Check that loadTestsFromModule honors (or not) a module # Check that loadTestsFromModule honors a module
# with a load_tests function. # with a load_tests function.
@warningregistry
def test_loadTestsFromModule__load_tests(self): def test_loadTestsFromModule__load_tests(self):
m = types.ModuleType('m') m = types.ModuleType('m')
class MyTestCase(unittest.TestCase): class MyTestCase(unittest.TestCase):
@ -195,126 +175,13 @@ class Test_TestLoader(unittest.TestCase):
suite = loader.loadTestsFromModule(m) suite = loader.loadTestsFromModule(m)
self.assertIsInstance(suite, unittest.TestSuite) self.assertIsInstance(suite, unittest.TestSuite)
self.assertEqual(load_tests_args, [loader, suite, None]) self.assertEqual(load_tests_args, [loader, suite, None])
# With Python 3.5, the undocumented and unofficial use_load_tests is
# ignored (and deprecated).
load_tests_args = []
with warnings.catch_warnings(record=False):
warnings.simplefilter('ignore')
suite = loader.loadTestsFromModule(m, use_load_tests=False)
self.assertEqual(load_tests_args, [loader, suite, None])
@warningregistry # In Python 3.11, the undocumented and unofficial use_load_tests has
def test_loadTestsFromModule__use_load_tests_deprecated_positional(self): # been removed.
m = types.ModuleType('m') with self.assertRaises(TypeError):
class MyTestCase(unittest.TestCase): loader.loadTestsFromModule(m, False)
def test(self): with self.assertRaises(TypeError):
pass loader.loadTestsFromModule(m, use_load_tests=False)
m.testcase_1 = MyTestCase
load_tests_args = []
def load_tests(loader, tests, pattern):
self.assertIsInstance(tests, unittest.TestSuite)
load_tests_args.extend((loader, tests, pattern))
return tests
m.load_tests = load_tests
# The method still works.
loader = unittest.TestLoader()
# use_load_tests=True as a positional argument.
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
suite = loader.loadTestsFromModule(m, False)
self.assertIsInstance(suite, unittest.TestSuite)
# load_tests was still called because use_load_tests is deprecated
# and ignored.
self.assertEqual(load_tests_args, [loader, suite, None])
# We got a warning.
self.assertIs(w[-1].category, DeprecationWarning)
self.assertEqual(str(w[-1].message),
'use_load_tests is deprecated and ignored')
@warningregistry
def test_loadTestsFromModule__use_load_tests_deprecated_keyword(self):
m = types.ModuleType('m')
class MyTestCase(unittest.TestCase):
def test(self):
pass
m.testcase_1 = MyTestCase
load_tests_args = []
def load_tests(loader, tests, pattern):
self.assertIsInstance(tests, unittest.TestSuite)
load_tests_args.extend((loader, tests, pattern))
return tests
m.load_tests = load_tests
# The method still works.
loader = unittest.TestLoader()
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
suite = loader.loadTestsFromModule(m, use_load_tests=False)
self.assertIsInstance(suite, unittest.TestSuite)
# load_tests was still called because use_load_tests is deprecated
# and ignored.
self.assertEqual(load_tests_args, [loader, suite, None])
# We got a warning.
self.assertIs(w[-1].category, DeprecationWarning)
self.assertEqual(str(w[-1].message),
'use_load_tests is deprecated and ignored')
@warningregistry
def test_loadTestsFromModule__too_many_positional_args(self):
m = types.ModuleType('m')
class MyTestCase(unittest.TestCase):
def test(self):
pass
m.testcase_1 = MyTestCase
load_tests_args = []
def load_tests(loader, tests, pattern):
self.assertIsInstance(tests, unittest.TestSuite)
load_tests_args.extend((loader, tests, pattern))
return tests
m.load_tests = load_tests
loader = unittest.TestLoader()
with self.assertRaises(TypeError) as cm, \
warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
loader.loadTestsFromModule(m, False, 'testme.*')
# We still got the deprecation warning.
self.assertIs(w[-1].category, DeprecationWarning)
self.assertEqual(str(w[-1].message),
'use_load_tests is deprecated and ignored')
# We also got a TypeError for too many positional arguments.
self.assertEqual(type(cm.exception), TypeError)
self.assertEqual(
str(cm.exception),
'loadTestsFromModule() takes 1 positional argument but 3 were given')
@warningregistry
def test_loadTestsFromModule__use_load_tests_other_bad_keyword(self):
m = types.ModuleType('m')
class MyTestCase(unittest.TestCase):
def test(self):
pass
m.testcase_1 = MyTestCase
load_tests_args = []
def load_tests(loader, tests, pattern):
self.assertIsInstance(tests, unittest.TestSuite)
load_tests_args.extend((loader, tests, pattern))
return tests
m.load_tests = load_tests
loader = unittest.TestLoader()
with warnings.catch_warnings():
warnings.simplefilter('ignore')
with self.assertRaises(TypeError) as cm:
loader.loadTestsFromModule(
m, use_load_tests=False, very_bad=True, worse=False)
self.assertEqual(type(cm.exception), TypeError)
# The error message names the first bad argument alphabetically,
# however use_load_tests (which sorts first) is ignored.
self.assertEqual(
str(cm.exception),
"loadTestsFromModule() got an unexpected keyword argument 'very_bad'")
def test_loadTestsFromModule__pattern(self): def test_loadTestsFromModule__pattern(self):
m = types.ModuleType('m') m = types.ModuleType('m')

View file

@ -426,14 +426,14 @@ class TestCommandLineArgs(unittest.TestCase):
return stderr.decode() return stderr.decode()
t = '_test_warnings' t = '_test_warnings'
self.assertIn('Ran 7 tests', run_unittest([t])) self.assertIn('Ran 5 tests', run_unittest([t]))
self.assertIn('Ran 7 tests', run_unittest(['-k', 'TestWarnings', t])) self.assertIn('Ran 5 tests', run_unittest(['-k', 'TestWarnings', t]))
self.assertIn('Ran 7 tests', run_unittest(['discover', '-p', '*_test*', '-k', 'TestWarnings'])) self.assertIn('Ran 5 tests', run_unittest(['discover', '-p', '*_test*', '-k', 'TestWarnings']))
self.assertIn('Ran 2 tests', run_unittest(['-k', 'f', t])) self.assertIn('Ran 1 test ', run_unittest(['-k', 'f', t]))
self.assertIn('Ran 7 tests', run_unittest(['-k', 't', t])) self.assertIn('Ran 5 tests', run_unittest(['-k', 't', t]))
self.assertIn('Ran 3 tests', run_unittest(['-k', '*t', t])) self.assertIn('Ran 2 tests', run_unittest(['-k', '*t', t]))
self.assertIn('Ran 7 tests', run_unittest(['-k', '*test_warnings.*Warning*', t])) self.assertIn('Ran 5 tests', run_unittest(['-k', '*test_warnings.*Warning*', t]))
self.assertIn('Ran 1 test', run_unittest(['-k', '*test_warnings.*warning*', t])) self.assertIn('Ran 1 test ', run_unittest(['-k', '*test_warnings.*warning*', t]))
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -1146,8 +1146,6 @@ class Test_TextTestRunner(unittest.TestCase):
return [b.splitlines() for b in p.communicate()] return [b.splitlines() for b in p.communicate()]
opts = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE, opts = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE,
cwd=os.path.dirname(__file__)) cwd=os.path.dirname(__file__))
ae_msg = b'Please use assertEqual instead.'
at_msg = b'Please use assertTrue instead.'
# no args -> all the warnings are printed, unittest warnings only once # no args -> all the warnings are printed, unittest warnings only once
p = subprocess.Popen([sys.executable, '-E', '_test_warnings.py'], **opts) p = subprocess.Popen([sys.executable, '-E', '_test_warnings.py'], **opts)
@ -1155,11 +1153,11 @@ class Test_TextTestRunner(unittest.TestCase):
out, err = get_parse_out_err(p) out, err = get_parse_out_err(p)
self.assertIn(b'OK', err) self.assertIn(b'OK', err)
# check that the total number of warnings in the output is correct # check that the total number of warnings in the output is correct
self.assertEqual(len(out), 12) self.assertEqual(len(out), 10)
# check that the numbers of the different kind of warnings is correct # check that the numbers of the different kind of warnings is correct
for msg in [b'dw', b'iw', b'uw']: for msg in [b'dw', b'iw', b'uw']:
self.assertEqual(out.count(msg), 3) self.assertEqual(out.count(msg), 3)
for msg in [ae_msg, at_msg, b'rw']: for msg in [b'rw']:
self.assertEqual(out.count(msg), 1) self.assertEqual(out.count(msg), 1)
args_list = ( args_list = (
@ -1186,11 +1184,9 @@ class Test_TextTestRunner(unittest.TestCase):
with p: with p:
out, err = get_parse_out_err(p) out, err = get_parse_out_err(p)
self.assertIn(b'OK', err) self.assertIn(b'OK', err)
self.assertEqual(len(out), 14) self.assertEqual(len(out), 12)
for msg in [b'dw', b'iw', b'uw', b'rw']: for msg in [b'dw', b'iw', b'uw', b'rw']:
self.assertEqual(out.count(msg), 3) self.assertEqual(out.count(msg), 3)
for msg in [ae_msg, at_msg]:
self.assertEqual(out.count(msg), 1)
def testStdErrLookedUpAtInstantiationTime(self): def testStdErrLookedUpAtInstantiationTime(self):
# see issue 10786 # see issue 10786

View file

@ -0,0 +1,6 @@
Remove many old deprecated :mod:`unittest` features:
* "``fail*``" and "``assert*``" aliases of :class:`~unittest.TestCase` methods.
* Broken from start :class:`~unittest.TestCase` method ``assertDictContainsSubset()``.
* Ignored :meth:`<unittest.TestLoader.loadTestsFromModule> TestLoader.loadTestsFromModule` parameter *use_load_tests*.
* Old alias ``_TextTestResult`` of :class:`~unittest.TextTestResult`.