Removed the Requirement to Install Python and NodeJS (Now Bundled with Borealis)

This commit is contained in:
2025-04-24 00:42:19 -06:00
parent 785265d3e7
commit 9c68cdea84
7786 changed files with 2386458 additions and 217 deletions

View File

@ -0,0 +1,6 @@
import os.path
from test.support import load_package_tests
def load_tests(*args):
return load_package_tests(os.path.dirname(__file__), *args)

View File

@ -0,0 +1,4 @@
from . import load_tests
import unittest
unittest.main()

View File

@ -0,0 +1,62 @@
# helper module for test_runner.Test_TextTestRunner.test_warnings
"""
This module has a number of tests that raise different kinds of warnings.
When the tests are run, the warnings are caught and their messages are printed
to stdout. This module also accepts an arg that is then passed to
unittest.main to affect the behavior of warnings.
Test_TextTestRunner.test_warnings executes this script with different
combinations of warnings args and -W flags and check that the output is correct.
See #10535.
"""
import sys
import unittest
import warnings
def warnfun():
warnings.warn('rw', RuntimeWarning)
class TestWarnings(unittest.TestCase):
def test_other_unittest(self):
self.assertAlmostEqual(2+2, 4)
self.assertNotAlmostEqual(4+4, 2)
# these warnings are normally silenced, but they are printed in unittest
def test_deprecation(self):
warnings.warn('dw', DeprecationWarning)
warnings.warn('dw', DeprecationWarning)
warnings.warn('dw', DeprecationWarning)
def test_import(self):
warnings.warn('iw', ImportWarning)
warnings.warn('iw', ImportWarning)
warnings.warn('iw', ImportWarning)
# user warnings should always be printed
def test_warning(self):
warnings.warn('uw')
warnings.warn('uw')
warnings.warn('uw')
# these warnings come from the same place; they will be printed
# only once by default or three times if the 'always' filter is used
def test_function(self):
warnfun()
warnfun()
warnfun()
if __name__ == '__main__':
with warnings.catch_warnings(record=True) as ws:
# if an arg is provided pass it to unittest.main as 'warnings'
if len(sys.argv) == 2:
unittest.main(exit=False, warnings=sys.argv.pop())
else:
unittest.main(exit=False)
# print all the warning messages collected
for w in ws:
print(w.message)

View File

@ -0,0 +1 @@
# Empty module for testing the loading of modules

View File

@ -0,0 +1,154 @@
import unittest
class TestEquality(object):
"""Used as a mixin for TestCase"""
# Check for a valid __eq__ implementation
def test_eq(self):
for obj_1, obj_2 in self.eq_pairs:
self.assertEqual(obj_1, obj_2)
self.assertEqual(obj_2, obj_1)
# Check for a valid __ne__ implementation
def test_ne(self):
for obj_1, obj_2 in self.ne_pairs:
self.assertNotEqual(obj_1, obj_2)
self.assertNotEqual(obj_2, obj_1)
class TestHashing(object):
"""Used as a mixin for TestCase"""
# Check for a valid __hash__ implementation
def test_hash(self):
for obj_1, obj_2 in self.eq_pairs:
try:
if not hash(obj_1) == hash(obj_2):
self.fail("%r and %r do not hash equal" % (obj_1, obj_2))
except Exception as e:
self.fail("Problem hashing %r and %r: %s" % (obj_1, obj_2, e))
for obj_1, obj_2 in self.ne_pairs:
try:
if hash(obj_1) == hash(obj_2):
self.fail("%s and %s hash equal, but shouldn't" %
(obj_1, obj_2))
except Exception as e:
self.fail("Problem hashing %s and %s: %s" % (obj_1, obj_2, e))
class _BaseLoggingResult(unittest.TestResult):
def __init__(self, log):
self._events = log
super().__init__()
def startTest(self, test):
self._events.append('startTest')
super().startTest(test)
def startTestRun(self):
self._events.append('startTestRun')
super().startTestRun()
def stopTest(self, test):
self._events.append('stopTest')
super().stopTest(test)
def stopTestRun(self):
self._events.append('stopTestRun')
super().stopTestRun()
def addFailure(self, *args):
self._events.append('addFailure')
super().addFailure(*args)
def addSuccess(self, *args):
self._events.append('addSuccess')
super().addSuccess(*args)
def addError(self, *args):
self._events.append('addError')
super().addError(*args)
def addSkip(self, *args):
self._events.append('addSkip')
super().addSkip(*args)
def addExpectedFailure(self, *args):
self._events.append('addExpectedFailure')
super().addExpectedFailure(*args)
def addUnexpectedSuccess(self, *args):
self._events.append('addUnexpectedSuccess')
super().addUnexpectedSuccess(*args)
class LegacyLoggingResult(_BaseLoggingResult):
"""
A legacy TestResult implementation, without an addSubTest method,
which records its method calls.
"""
@property
def addSubTest(self):
raise AttributeError
class LoggingResult(_BaseLoggingResult):
"""
A TestResult implementation which records its method calls.
"""
def addSubTest(self, test, subtest, err):
if err is None:
self._events.append('addSubTestSuccess')
else:
self._events.append('addSubTestFailure')
super().addSubTest(test, subtest, err)
class ResultWithNoStartTestRunStopTestRun(object):
"""An object honouring TestResult before startTestRun/stopTestRun."""
def __init__(self):
self.failures = []
self.errors = []
self.testsRun = 0
self.skipped = []
self.expectedFailures = []
self.unexpectedSuccesses = []
self.shouldStop = False
def startTest(self, test):
pass
def stopTest(self, test):
pass
def addError(self, test):
pass
def addFailure(self, test):
pass
def addSuccess(self, test):
pass
def wasSuccessful(self):
return True
class BufferedWriter:
def __init__(self):
self.result = ''
self.buffer = ''
def write(self, arg):
self.buffer += arg
def flush(self):
self.result += self.buffer
self.buffer = ''
def getvalue(self):
return self.result

View File

@ -0,0 +1,417 @@
import datetime
import warnings
import weakref
import unittest
from test.support import gc_collect
from itertools import product
class Test_Assertions(unittest.TestCase):
def test_AlmostEqual(self):
self.assertAlmostEqual(1.00000001, 1.0)
self.assertNotAlmostEqual(1.0000001, 1.0)
self.assertRaises(self.failureException,
self.assertAlmostEqual, 1.0000001, 1.0)
self.assertRaises(self.failureException,
self.assertNotAlmostEqual, 1.00000001, 1.0)
self.assertAlmostEqual(1.1, 1.0, places=0)
self.assertRaises(self.failureException,
self.assertAlmostEqual, 1.1, 1.0, places=1)
self.assertAlmostEqual(0, .1+.1j, places=0)
self.assertNotAlmostEqual(0, .1+.1j, places=1)
self.assertRaises(self.failureException,
self.assertAlmostEqual, 0, .1+.1j, places=1)
self.assertRaises(self.failureException,
self.assertNotAlmostEqual, 0, .1+.1j, places=0)
self.assertAlmostEqual(float('inf'), float('inf'))
self.assertRaises(self.failureException, self.assertNotAlmostEqual,
float('inf'), float('inf'))
def test_AmostEqualWithDelta(self):
self.assertAlmostEqual(1.1, 1.0, delta=0.5)
self.assertAlmostEqual(1.0, 1.1, delta=0.5)
self.assertNotAlmostEqual(1.1, 1.0, delta=0.05)
self.assertNotAlmostEqual(1.0, 1.1, delta=0.05)
self.assertAlmostEqual(1.0, 1.0, delta=0.5)
self.assertRaises(self.failureException, self.assertNotAlmostEqual,
1.0, 1.0, delta=0.5)
self.assertRaises(self.failureException, self.assertAlmostEqual,
1.1, 1.0, delta=0.05)
self.assertRaises(self.failureException, self.assertNotAlmostEqual,
1.1, 1.0, delta=0.5)
self.assertRaises(TypeError, self.assertAlmostEqual,
1.1, 1.0, places=2, delta=2)
self.assertRaises(TypeError, self.assertNotAlmostEqual,
1.1, 1.0, places=2, delta=2)
first = datetime.datetime.now()
second = first + datetime.timedelta(seconds=10)
self.assertAlmostEqual(first, second,
delta=datetime.timedelta(seconds=20))
self.assertNotAlmostEqual(first, second,
delta=datetime.timedelta(seconds=5))
def test_assertRaises(self):
def _raise(e):
raise e
self.assertRaises(KeyError, _raise, KeyError)
self.assertRaises(KeyError, _raise, KeyError("key"))
try:
self.assertRaises(KeyError, lambda: None)
except self.failureException as e:
self.assertIn("KeyError not raised", str(e))
else:
self.fail("assertRaises() didn't fail")
try:
self.assertRaises(KeyError, _raise, ValueError)
except ValueError:
pass
else:
self.fail("assertRaises() didn't let exception pass through")
with self.assertRaises(KeyError) as cm:
try:
raise KeyError
except Exception as e:
exc = e
raise
self.assertIs(cm.exception, exc)
with self.assertRaises(KeyError):
raise KeyError("key")
try:
with self.assertRaises(KeyError):
pass
except self.failureException as e:
self.assertIn("KeyError not raised", str(e))
else:
self.fail("assertRaises() didn't fail")
try:
with self.assertRaises(KeyError):
raise ValueError
except ValueError:
pass
else:
self.fail("assertRaises() didn't let exception pass through")
def test_assertRaises_frames_survival(self):
# Issue #9815: assertRaises should avoid keeping local variables
# in a traceback alive.
class A:
pass
wr = None
class Foo(unittest.TestCase):
def foo(self):
nonlocal wr
a = A()
wr = weakref.ref(a)
try:
raise OSError
except OSError:
raise ValueError
def test_functional(self):
self.assertRaises(ValueError, self.foo)
def test_with(self):
with self.assertRaises(ValueError):
self.foo()
Foo("test_functional").run()
gc_collect() # For PyPy or other GCs.
self.assertIsNone(wr())
Foo("test_with").run()
gc_collect() # For PyPy or other GCs.
self.assertIsNone(wr())
def testAssertNotRegex(self):
self.assertNotRegex('Ala ma kota', r'r+')
try:
self.assertNotRegex('Ala ma kota', r'k.t', 'Message')
except self.failureException as e:
self.assertIn('Message', e.args[0])
else:
self.fail('assertNotRegex should have failed.')
class TestLongMessage(unittest.TestCase):
"""Test that the individual asserts honour longMessage.
This actually tests all the message behaviour for
asserts that use longMessage."""
def setUp(self):
class TestableTestFalse(unittest.TestCase):
longMessage = False
failureException = self.failureException
def testTest(self):
pass
class TestableTestTrue(unittest.TestCase):
longMessage = True
failureException = self.failureException
def testTest(self):
pass
self.testableTrue = TestableTestTrue('testTest')
self.testableFalse = TestableTestFalse('testTest')
def testDefault(self):
self.assertTrue(unittest.TestCase.longMessage)
def test_formatMsg(self):
self.assertEqual(self.testableFalse._formatMessage(None, "foo"), "foo")
self.assertEqual(self.testableFalse._formatMessage("foo", "bar"), "foo")
self.assertEqual(self.testableTrue._formatMessage(None, "foo"), "foo")
self.assertEqual(self.testableTrue._formatMessage("foo", "bar"), "bar : foo")
# This blows up if _formatMessage uses string concatenation
self.testableTrue._formatMessage(object(), 'foo')
def test_formatMessage_unicode_error(self):
one = ''.join(chr(i) for i in range(255))
# this used to cause a UnicodeDecodeError constructing msg
self.testableTrue._formatMessage(one, '\uFFFD')
def assertMessages(self, methodName, args, errors):
"""
Check that methodName(*args) raises the correct error messages.
errors should be a list of 4 regex that match the error when:
1) longMessage = False and no msg passed;
2) longMessage = False and msg passed;
3) longMessage = True and no msg passed;
4) longMessage = True and msg passed;
"""
def getMethod(i):
useTestableFalse = i < 2
if useTestableFalse:
test = self.testableFalse
else:
test = self.testableTrue
return getattr(test, methodName)
for i, expected_regex in enumerate(errors):
testMethod = getMethod(i)
kwargs = {}
withMsg = i % 2
if withMsg:
kwargs = {"msg": "oops"}
with self.assertRaisesRegex(self.failureException,
expected_regex=expected_regex):
testMethod(*args, **kwargs)
def testAssertTrue(self):
self.assertMessages('assertTrue', (False,),
["^False is not true$", "^oops$", "^False is not true$",
"^False is not true : oops$"])
def testAssertFalse(self):
self.assertMessages('assertFalse', (True,),
["^True is not false$", "^oops$", "^True is not false$",
"^True is not false : oops$"])
def testNotEqual(self):
self.assertMessages('assertNotEqual', (1, 1),
["^1 == 1$", "^oops$", "^1 == 1$",
"^1 == 1 : oops$"])
def testAlmostEqual(self):
self.assertMessages(
'assertAlmostEqual', (1, 2),
[r"^1 != 2 within 7 places \(1 difference\)$", "^oops$",
r"^1 != 2 within 7 places \(1 difference\)$",
r"^1 != 2 within 7 places \(1 difference\) : oops$"])
def testNotAlmostEqual(self):
self.assertMessages('assertNotAlmostEqual', (1, 1),
["^1 == 1 within 7 places$", "^oops$",
"^1 == 1 within 7 places$", "^1 == 1 within 7 places : oops$"])
def test_baseAssertEqual(self):
self.assertMessages('_baseAssertEqual', (1, 2),
["^1 != 2$", "^oops$", "^1 != 2$", "^1 != 2 : oops$"])
def testAssertSequenceEqual(self):
# Error messages are multiline so not testing on full message
# assertTupleEqual and assertListEqual delegate to this method
self.assertMessages('assertSequenceEqual', ([], [None]),
[r"\+ \[None\]$", "^oops$", r"\+ \[None\]$",
r"\+ \[None\] : oops$"])
def testAssertSetEqual(self):
self.assertMessages('assertSetEqual', (set(), set([None])),
["None$", "^oops$", "None$",
"None : oops$"])
def testAssertIn(self):
self.assertMessages('assertIn', (None, []),
[r'^None not found in \[\]$', "^oops$",
r'^None not found in \[\]$',
r'^None not found in \[\] : oops$'])
def testAssertNotIn(self):
self.assertMessages('assertNotIn', (None, [None]),
[r'^None unexpectedly found in \[None\]$', "^oops$",
r'^None unexpectedly found in \[None\]$',
r'^None unexpectedly found in \[None\] : oops$'])
def testAssertDictEqual(self):
self.assertMessages('assertDictEqual', ({}, {'key': 'value'}),
[r"\+ \{'key': 'value'\}$", "^oops$",
r"\+ \{'key': 'value'\}$",
r"\+ \{'key': 'value'\} : oops$"])
def testAssertMultiLineEqual(self):
self.assertMessages('assertMultiLineEqual', ("", "foo"),
[r"\+ foo\n$", "^oops$",
r"\+ foo\n$",
r"\+ foo\n : oops$"])
def testAssertLess(self):
self.assertMessages('assertLess', (2, 1),
["^2 not less than 1$", "^oops$",
"^2 not less than 1$", "^2 not less than 1 : oops$"])
def testAssertLessEqual(self):
self.assertMessages('assertLessEqual', (2, 1),
["^2 not less than or equal to 1$", "^oops$",
"^2 not less than or equal to 1$",
"^2 not less than or equal to 1 : oops$"])
def testAssertGreater(self):
self.assertMessages('assertGreater', (1, 2),
["^1 not greater than 2$", "^oops$",
"^1 not greater than 2$",
"^1 not greater than 2 : oops$"])
def testAssertGreaterEqual(self):
self.assertMessages('assertGreaterEqual', (1, 2),
["^1 not greater than or equal to 2$", "^oops$",
"^1 not greater than or equal to 2$",
"^1 not greater than or equal to 2 : oops$"])
def testAssertIsNone(self):
self.assertMessages('assertIsNone', ('not None',),
["^'not None' is not None$", "^oops$",
"^'not None' is not None$",
"^'not None' is not None : oops$"])
def testAssertIsNotNone(self):
self.assertMessages('assertIsNotNone', (None,),
["^unexpectedly None$", "^oops$",
"^unexpectedly None$",
"^unexpectedly None : oops$"])
def testAssertIs(self):
self.assertMessages('assertIs', (None, 'foo'),
["^None is not 'foo'$", "^oops$",
"^None is not 'foo'$",
"^None is not 'foo' : oops$"])
def testAssertIsNot(self):
self.assertMessages('assertIsNot', (None, None),
["^unexpectedly identical: None$", "^oops$",
"^unexpectedly identical: None$",
"^unexpectedly identical: None : oops$"])
def testAssertRegex(self):
self.assertMessages('assertRegex', ('foo', 'bar'),
["^Regex didn't match:",
"^oops$",
"^Regex didn't match:",
"^Regex didn't match: (.*) : oops$"])
def testAssertNotRegex(self):
self.assertMessages('assertNotRegex', ('foo', 'foo'),
["^Regex matched:",
"^oops$",
"^Regex matched:",
"^Regex matched: (.*) : oops$"])
def assertMessagesCM(self, methodName, args, func, errors):
"""
Check that the correct error messages are raised while executing:
with method(*args):
func()
*errors* should be a list of 4 regex that match the error when:
1) longMessage = False and no msg passed;
2) longMessage = False and msg passed;
3) longMessage = True and no msg passed;
4) longMessage = True and msg passed;
"""
p = product((self.testableFalse, self.testableTrue),
({}, {"msg": "oops"}))
for (cls, kwargs), err in zip(p, errors):
method = getattr(cls, methodName)
with self.assertRaisesRegex(cls.failureException, err):
with method(*args, **kwargs) as cm:
func()
def testAssertRaises(self):
self.assertMessagesCM('assertRaises', (TypeError,), lambda: None,
['^TypeError not raised$', '^oops$',
'^TypeError not raised$',
'^TypeError not raised : oops$'])
def testAssertRaisesRegex(self):
# test error not raised
self.assertMessagesCM('assertRaisesRegex', (TypeError, 'unused regex'),
lambda: None,
['^TypeError not raised$', '^oops$',
'^TypeError not raised$',
'^TypeError not raised : oops$'])
# test error raised but with wrong message
def raise_wrong_message():
raise TypeError('foo')
self.assertMessagesCM('assertRaisesRegex', (TypeError, 'regex'),
raise_wrong_message,
['^"regex" does not match "foo"$', '^oops$',
'^"regex" does not match "foo"$',
'^"regex" does not match "foo" : oops$'])
def testAssertWarns(self):
self.assertMessagesCM('assertWarns', (UserWarning,), lambda: None,
['^UserWarning not triggered$', '^oops$',
'^UserWarning not triggered$',
'^UserWarning not triggered : oops$'])
def test_assertNotWarns(self):
def warn_future():
warnings.warn('xyz', FutureWarning, stacklevel=2)
self.assertMessagesCM('_assertNotWarns', (FutureWarning,),
warn_future,
['^FutureWarning triggered$',
'^oops$',
'^FutureWarning triggered$',
'^FutureWarning triggered : oops$'])
def testAssertWarnsRegex(self):
# test error not raised
self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'unused regex'),
lambda: None,
['^UserWarning not triggered$', '^oops$',
'^UserWarning not triggered$',
'^UserWarning not triggered : oops$'])
# test warning raised but with wrong message
def raise_wrong_message():
warnings.warn('foo')
self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'regex'),
raise_wrong_message,
['^"regex" does not match "foo"$', '^oops$',
'^"regex" does not match "foo"$',
'^"regex" does not match "foo" : oops$'])
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,502 @@
import asyncio
import contextvars
import unittest
from test import support
support.requires_working_socket(module=True)
class MyException(Exception):
pass
def tearDownModule():
asyncio.set_event_loop_policy(None)
class TestCM:
def __init__(self, ordering, enter_result=None):
self.ordering = ordering
self.enter_result = enter_result
async def __aenter__(self):
self.ordering.append('enter')
return self.enter_result
async def __aexit__(self, *exc_info):
self.ordering.append('exit')
class LacksEnterAndExit:
pass
class LacksEnter:
async def __aexit__(self, *exc_info):
pass
class LacksExit:
async def __aenter__(self):
pass
VAR = contextvars.ContextVar('VAR', default=())
class TestAsyncCase(unittest.TestCase):
maxDiff = None
def setUp(self):
# Ensure that IsolatedAsyncioTestCase instances are destroyed before
# starting a new event loop
self.addCleanup(support.gc_collect)
def test_full_cycle(self):
expected = ['setUp',
'asyncSetUp',
'test',
'asyncTearDown',
'tearDown',
'cleanup6',
'cleanup5',
'cleanup4',
'cleanup3',
'cleanup2',
'cleanup1']
class Test(unittest.IsolatedAsyncioTestCase):
def setUp(self):
self.assertEqual(events, [])
events.append('setUp')
VAR.set(VAR.get() + ('setUp',))
self.addCleanup(self.on_cleanup1)
self.addAsyncCleanup(self.on_cleanup2)
async def asyncSetUp(self):
self.assertEqual(events, expected[:1])
events.append('asyncSetUp')
VAR.set(VAR.get() + ('asyncSetUp',))
self.addCleanup(self.on_cleanup3)
self.addAsyncCleanup(self.on_cleanup4)
async def test_func(self):
self.assertEqual(events, expected[:2])
events.append('test')
VAR.set(VAR.get() + ('test',))
self.addCleanup(self.on_cleanup5)
self.addAsyncCleanup(self.on_cleanup6)
async def asyncTearDown(self):
self.assertEqual(events, expected[:3])
VAR.set(VAR.get() + ('asyncTearDown',))
events.append('asyncTearDown')
def tearDown(self):
self.assertEqual(events, expected[:4])
events.append('tearDown')
VAR.set(VAR.get() + ('tearDown',))
def on_cleanup1(self):
self.assertEqual(events, expected[:10])
events.append('cleanup1')
VAR.set(VAR.get() + ('cleanup1',))
nonlocal cvar
cvar = VAR.get()
async def on_cleanup2(self):
self.assertEqual(events, expected[:9])
events.append('cleanup2')
VAR.set(VAR.get() + ('cleanup2',))
def on_cleanup3(self):
self.assertEqual(events, expected[:8])
events.append('cleanup3')
VAR.set(VAR.get() + ('cleanup3',))
async def on_cleanup4(self):
self.assertEqual(events, expected[:7])
events.append('cleanup4')
VAR.set(VAR.get() + ('cleanup4',))
def on_cleanup5(self):
self.assertEqual(events, expected[:6])
events.append('cleanup5')
VAR.set(VAR.get() + ('cleanup5',))
async def on_cleanup6(self):
self.assertEqual(events, expected[:5])
events.append('cleanup6')
VAR.set(VAR.get() + ('cleanup6',))
events = []
cvar = ()
test = Test("test_func")
result = test.run()
self.assertEqual(result.errors, [])
self.assertEqual(result.failures, [])
self.assertEqual(events, expected)
self.assertEqual(cvar, tuple(expected))
events = []
cvar = ()
test = Test("test_func")
test.debug()
self.assertEqual(events, expected)
self.assertEqual(cvar, tuple(expected))
test.doCleanups()
self.assertEqual(events, expected)
self.assertEqual(cvar, tuple(expected))
def test_exception_in_setup(self):
class Test(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
events.append('asyncSetUp')
self.addAsyncCleanup(self.on_cleanup)
raise MyException()
async def test_func(self):
events.append('test')
async def asyncTearDown(self):
events.append('asyncTearDown')
async def on_cleanup(self):
events.append('cleanup')
events = []
test = Test("test_func")
result = test.run()
self.assertEqual(events, ['asyncSetUp', 'cleanup'])
self.assertIs(result.errors[0][0], test)
self.assertIn('MyException', result.errors[0][1])
events = []
test = Test("test_func")
self.addCleanup(test._tearDownAsyncioRunner)
try:
test.debug()
except MyException:
pass
else:
self.fail('Expected a MyException exception')
self.assertEqual(events, ['asyncSetUp'])
test.doCleanups()
self.assertEqual(events, ['asyncSetUp', 'cleanup'])
def test_exception_in_test(self):
class Test(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
events.append('asyncSetUp')
async def test_func(self):
events.append('test')
self.addAsyncCleanup(self.on_cleanup)
raise MyException()
async def asyncTearDown(self):
events.append('asyncTearDown')
async def on_cleanup(self):
events.append('cleanup')
events = []
test = Test("test_func")
result = test.run()
self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup'])
self.assertIs(result.errors[0][0], test)
self.assertIn('MyException', result.errors[0][1])
events = []
test = Test("test_func")
self.addCleanup(test._tearDownAsyncioRunner)
try:
test.debug()
except MyException:
pass
else:
self.fail('Expected a MyException exception')
self.assertEqual(events, ['asyncSetUp', 'test'])
test.doCleanups()
self.assertEqual(events, ['asyncSetUp', 'test', 'cleanup'])
def test_exception_in_tear_down(self):
class Test(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
events.append('asyncSetUp')
async def test_func(self):
events.append('test')
self.addAsyncCleanup(self.on_cleanup)
async def asyncTearDown(self):
events.append('asyncTearDown')
raise MyException()
async def on_cleanup(self):
events.append('cleanup')
events = []
test = Test("test_func")
result = test.run()
self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup'])
self.assertIs(result.errors[0][0], test)
self.assertIn('MyException', result.errors[0][1])
events = []
test = Test("test_func")
self.addCleanup(test._tearDownAsyncioRunner)
try:
test.debug()
except MyException:
pass
else:
self.fail('Expected a MyException exception')
self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown'])
test.doCleanups()
self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup'])
def test_exception_in_tear_clean_up(self):
class Test(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
events.append('asyncSetUp')
async def test_func(self):
events.append('test')
self.addAsyncCleanup(self.on_cleanup1)
self.addAsyncCleanup(self.on_cleanup2)
async def asyncTearDown(self):
events.append('asyncTearDown')
async def on_cleanup1(self):
events.append('cleanup1')
raise MyException('some error')
async def on_cleanup2(self):
events.append('cleanup2')
raise MyException('other error')
events = []
test = Test("test_func")
result = test.run()
self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup2', 'cleanup1'])
self.assertIs(result.errors[0][0], test)
self.assertIn('MyException: other error', result.errors[0][1])
self.assertIn('MyException: some error', result.errors[1][1])
events = []
test = Test("test_func")
self.addCleanup(test._tearDownAsyncioRunner)
try:
test.debug()
except MyException:
pass
else:
self.fail('Expected a MyException exception')
self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup2'])
test.doCleanups()
self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup2', 'cleanup1'])
def test_deprecation_of_return_val_from_test(self):
# Issue 41322 - deprecate return of value that is not None from a test
class Nothing:
def __eq__(self, o):
return o is None
class Test(unittest.IsolatedAsyncioTestCase):
async def test1(self):
return 1
async def test2(self):
yield 1
async def test3(self):
return Nothing()
with self.assertWarns(DeprecationWarning) as w:
Test('test1').run()
self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
self.assertIn('test1', str(w.warning))
self.assertEqual(w.filename, __file__)
with self.assertWarns(DeprecationWarning) as w:
Test('test2').run()
self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
self.assertIn('test2', str(w.warning))
self.assertEqual(w.filename, __file__)
with self.assertWarns(DeprecationWarning) as w:
Test('test3').run()
self.assertIn('It is deprecated to return a value that is not None', str(w.warning))
self.assertIn('test3', str(w.warning))
self.assertEqual(w.filename, __file__)
def test_cleanups_interleave_order(self):
events = []
class Test(unittest.IsolatedAsyncioTestCase):
async def test_func(self):
self.addAsyncCleanup(self.on_sync_cleanup, 1)
self.addAsyncCleanup(self.on_async_cleanup, 2)
self.addAsyncCleanup(self.on_sync_cleanup, 3)
self.addAsyncCleanup(self.on_async_cleanup, 4)
async def on_sync_cleanup(self, val):
events.append(f'sync_cleanup {val}')
async def on_async_cleanup(self, val):
events.append(f'async_cleanup {val}')
test = Test("test_func")
test.run()
self.assertEqual(events, ['async_cleanup 4',
'sync_cleanup 3',
'async_cleanup 2',
'sync_cleanup 1'])
def test_base_exception_from_async_method(self):
events = []
class Test(unittest.IsolatedAsyncioTestCase):
async def test_base(self):
events.append("test_base")
raise BaseException()
events.append("not it")
async def test_no_err(self):
events.append("test_no_err")
async def test_cancel(self):
raise asyncio.CancelledError()
test = Test("test_base")
output = test.run()
self.assertFalse(output.wasSuccessful())
test = Test("test_no_err")
test.run()
self.assertEqual(events, ['test_base', 'test_no_err'])
test = Test("test_cancel")
output = test.run()
self.assertFalse(output.wasSuccessful())
def test_cancellation_hanging_tasks(self):
cancelled = False
class Test(unittest.IsolatedAsyncioTestCase):
async def test_leaking_task(self):
async def coro():
nonlocal cancelled
try:
await asyncio.sleep(1)
except asyncio.CancelledError:
cancelled = True
raise
# Leave this running in the background
asyncio.create_task(coro())
test = Test("test_leaking_task")
output = test.run()
self.assertTrue(cancelled)
def test_enterAsyncContext(self):
events = []
class Test(unittest.IsolatedAsyncioTestCase):
async def test_func(slf):
slf.addAsyncCleanup(events.append, 'cleanup1')
cm = TestCM(events, 42)
self.assertEqual(await slf.enterAsyncContext(cm), 42)
slf.addAsyncCleanup(events.append, 'cleanup2')
events.append('test')
test = Test('test_func')
output = test.run()
self.assertTrue(output.wasSuccessful(), output)
self.assertEqual(events, ['enter', 'test', 'cleanup2', 'exit', 'cleanup1'])
def test_enterAsyncContext_arg_errors(self):
class Test(unittest.IsolatedAsyncioTestCase):
async def test_func(slf):
with self.assertRaisesRegex(TypeError, 'asynchronous context manager'):
await slf.enterAsyncContext(LacksEnterAndExit())
with self.assertRaisesRegex(TypeError, 'asynchronous context manager'):
await slf.enterAsyncContext(LacksEnter())
with self.assertRaisesRegex(TypeError, 'asynchronous context manager'):
await slf.enterAsyncContext(LacksExit())
test = Test('test_func')
output = test.run()
self.assertTrue(output.wasSuccessful())
def test_debug_cleanup_same_loop(self):
class Test(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
async def coro():
await asyncio.sleep(0)
fut = asyncio.ensure_future(coro())
self.addAsyncCleanup(self.cleanup, fut)
events.append('asyncSetUp')
async def test_func(self):
events.append('test')
raise MyException()
async def asyncTearDown(self):
events.append('asyncTearDown')
async def cleanup(self, fut):
try:
# Raises an exception if in different loop
await asyncio.wait([fut])
events.append('cleanup')
except:
import traceback
traceback.print_exc()
raise
events = []
test = Test("test_func")
result = test.run()
self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup'])
self.assertIn('MyException', result.errors[0][1])
events = []
test = Test("test_func")
self.addCleanup(test._tearDownAsyncioRunner)
try:
test.debug()
except MyException:
pass
else:
self.fail('Expected a MyException exception')
self.assertEqual(events, ['asyncSetUp', 'test'])
test.doCleanups()
self.assertEqual(events, ['asyncSetUp', 'test', 'cleanup'])
def test_setup_get_event_loop(self):
# See https://github.com/python/cpython/issues/95736
# Make sure the default event loop is not used
asyncio.set_event_loop(None)
class TestCase1(unittest.IsolatedAsyncioTestCase):
def setUp(self):
asyncio.get_event_loop_policy().get_event_loop()
async def test_demo1(self):
pass
test = TestCase1('test_demo1')
result = test.run()
self.assertTrue(result.wasSuccessful())
def test_loop_factory(self):
asyncio.set_event_loop_policy(None)
class TestCase1(unittest.IsolatedAsyncioTestCase):
loop_factory = asyncio.EventLoop
async def test_demo1(self):
pass
test = TestCase1('test_demo1')
result = test.run()
self.assertTrue(result.wasSuccessful())
self.assertIsNone(support.maybe_get_event_loop_policy())
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,309 @@
import gc
import io
import os
import sys
import signal
import weakref
import unittest
from test import support
@unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
@unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
class TestBreak(unittest.TestCase):
int_handler = None
# This number was smart-guessed, previously tests were failing
# after 7th run. So, we take `x * 2 + 1` to be sure.
default_repeats = 15
def setUp(self):
self._default_handler = signal.getsignal(signal.SIGINT)
if self.int_handler is not None:
signal.signal(signal.SIGINT, self.int_handler)
def tearDown(self):
signal.signal(signal.SIGINT, self._default_handler)
unittest.signals._results = weakref.WeakKeyDictionary()
unittest.signals._interrupt_handler = None
def withRepeats(self, test_function, repeats=None):
if not support.check_impl_detail(cpython=True):
# Override repeats count on non-cpython to execute only once.
# Because this test only makes sense to be repeated on CPython.
repeats = 1
elif repeats is None:
repeats = self.default_repeats
for repeat in range(repeats):
with self.subTest(repeat=repeat):
# We don't run `setUp` for the very first repeat
# and we don't run `tearDown` for the very last one,
# because they are handled by the test class itself.
if repeat != 0:
self.setUp()
try:
test_function()
finally:
if repeat != repeats - 1:
self.tearDown()
def testInstallHandler(self):
default_handler = signal.getsignal(signal.SIGINT)
unittest.installHandler()
self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler)
try:
pid = os.getpid()
os.kill(pid, signal.SIGINT)
except KeyboardInterrupt:
self.fail("KeyboardInterrupt not handled")
self.assertTrue(unittest.signals._interrupt_handler.called)
def testRegisterResult(self):
result = unittest.TestResult()
self.assertNotIn(result, unittest.signals._results)
unittest.registerResult(result)
try:
self.assertIn(result, unittest.signals._results)
finally:
unittest.removeResult(result)
def testInterruptCaught(self):
def test(result):
pid = os.getpid()
os.kill(pid, signal.SIGINT)
result.breakCaught = True
self.assertTrue(result.shouldStop)
def test_function():
result = unittest.TestResult()
unittest.installHandler()
unittest.registerResult(result)
self.assertNotEqual(
signal.getsignal(signal.SIGINT),
self._default_handler,
)
try:
test(result)
except KeyboardInterrupt:
self.fail("KeyboardInterrupt not handled")
self.assertTrue(result.breakCaught)
self.withRepeats(test_function)
def testSecondInterrupt(self):
# Can't use skipIf decorator because the signal handler may have
# been changed after defining this method.
if signal.getsignal(signal.SIGINT) == signal.SIG_IGN:
self.skipTest("test requires SIGINT to not be ignored")
def test(result):
pid = os.getpid()
os.kill(pid, signal.SIGINT)
result.breakCaught = True
self.assertTrue(result.shouldStop)
os.kill(pid, signal.SIGINT)
self.fail("Second KeyboardInterrupt not raised")
def test_function():
result = unittest.TestResult()
unittest.installHandler()
unittest.registerResult(result)
with self.assertRaises(KeyboardInterrupt):
test(result)
self.assertTrue(result.breakCaught)
self.withRepeats(test_function)
def testTwoResults(self):
def test_function():
unittest.installHandler()
result = unittest.TestResult()
unittest.registerResult(result)
new_handler = signal.getsignal(signal.SIGINT)
result2 = unittest.TestResult()
unittest.registerResult(result2)
self.assertEqual(signal.getsignal(signal.SIGINT), new_handler)
result3 = unittest.TestResult()
try:
os.kill(os.getpid(), signal.SIGINT)
except KeyboardInterrupt:
self.fail("KeyboardInterrupt not handled")
self.assertTrue(result.shouldStop)
self.assertTrue(result2.shouldStop)
self.assertFalse(result3.shouldStop)
self.withRepeats(test_function)
def testHandlerReplacedButCalled(self):
# Can't use skipIf decorator because the signal handler may have
# been changed after defining this method.
if signal.getsignal(signal.SIGINT) == signal.SIG_IGN:
self.skipTest("test requires SIGINT to not be ignored")
def test_function():
# If our handler has been replaced (is no longer installed) but is
# called by the *new* handler, then it isn't safe to delay the
# SIGINT and we should immediately delegate to the default handler
unittest.installHandler()
handler = signal.getsignal(signal.SIGINT)
def new_handler(frame, signum):
handler(frame, signum)
signal.signal(signal.SIGINT, new_handler)
try:
os.kill(os.getpid(), signal.SIGINT)
except KeyboardInterrupt:
pass
else:
self.fail("replaced but delegated handler doesn't raise interrupt")
self.withRepeats(test_function)
def testRunner(self):
# Creating a TextTestRunner with the appropriate argument should
# register the TextTestResult it creates
runner = unittest.TextTestRunner(stream=io.StringIO())
result = runner.run(unittest.TestSuite())
self.assertIn(result, unittest.signals._results)
def testWeakReferences(self):
# Calling registerResult on a result should not keep it alive
result = unittest.TestResult()
unittest.registerResult(result)
ref = weakref.ref(result)
del result
# For non-reference counting implementations
gc.collect();gc.collect()
self.assertIsNone(ref())
def testRemoveResult(self):
result = unittest.TestResult()
unittest.registerResult(result)
unittest.installHandler()
self.assertTrue(unittest.removeResult(result))
# Should this raise an error instead?
self.assertFalse(unittest.removeResult(unittest.TestResult()))
try:
pid = os.getpid()
os.kill(pid, signal.SIGINT)
except KeyboardInterrupt:
pass
self.assertFalse(result.shouldStop)
def testMainInstallsHandler(self):
failfast = object()
test = object()
verbosity = object()
result = object()
default_handler = signal.getsignal(signal.SIGINT)
class FakeRunner(object):
initArgs = []
runArgs = []
def __init__(self, *args, **kwargs):
self.initArgs.append((args, kwargs))
def run(self, test):
self.runArgs.append(test)
return result
class Program(unittest.TestProgram):
def __init__(self, catchbreak):
self.exit = False
self.verbosity = verbosity
self.failfast = failfast
self.catchbreak = catchbreak
self.tb_locals = False
self.testRunner = FakeRunner
self.test = test
self.result = None
self.durations = None
p = Program(False)
p.runTests()
self.assertEqual(FakeRunner.initArgs, [((), {'buffer': None,
'verbosity': verbosity,
'failfast': failfast,
'tb_locals': False,
'warnings': None,
'durations': None})])
self.assertEqual(FakeRunner.runArgs, [test])
self.assertEqual(p.result, result)
self.assertEqual(signal.getsignal(signal.SIGINT), default_handler)
FakeRunner.initArgs = []
FakeRunner.runArgs = []
p = Program(True)
p.runTests()
self.assertEqual(FakeRunner.initArgs, [((), {'buffer': None,
'verbosity': verbosity,
'failfast': failfast,
'tb_locals': False,
'warnings': None,
'durations': None})])
self.assertEqual(FakeRunner.runArgs, [test])
self.assertEqual(p.result, result)
self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler)
def testRemoveHandler(self):
default_handler = signal.getsignal(signal.SIGINT)
unittest.installHandler()
unittest.removeHandler()
self.assertEqual(signal.getsignal(signal.SIGINT), default_handler)
# check that calling removeHandler multiple times has no ill-effect
unittest.removeHandler()
self.assertEqual(signal.getsignal(signal.SIGINT), default_handler)
def testRemoveHandlerAsDecorator(self):
default_handler = signal.getsignal(signal.SIGINT)
unittest.installHandler()
@unittest.removeHandler
def test():
self.assertEqual(signal.getsignal(signal.SIGINT), default_handler)
test()
self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler)
@unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
@unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
class TestBreakDefaultIntHandler(TestBreak):
int_handler = signal.default_int_handler
@unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
@unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
class TestBreakSignalIgnored(TestBreak):
int_handler = signal.SIG_IGN
@unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
@unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
class TestBreakSignalDefault(TestBreak):
int_handler = signal.SIG_DFL
if __name__ == "__main__":
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,874 @@
import os.path
from os.path import abspath
import re
import sys
import types
import pickle
from test import support
from test.support import import_helper
import unittest
import unittest.mock
import test.test_unittest
class TestableTestProgram(unittest.TestProgram):
module = None
exit = True
defaultTest = failfast = catchbreak = buffer = None
verbosity = 1
progName = ''
testRunner = testLoader = None
def __init__(self):
pass
class TestDiscovery(unittest.TestCase):
# Heavily mocked tests so I can avoid hitting the filesystem
def test_get_name_from_path(self):
loader = unittest.TestLoader()
loader._top_level_dir = '/foo'
name = loader._get_name_from_path('/foo/bar/baz.py')
self.assertEqual(name, 'bar.baz')
if not __debug__:
# asserts are off
return
with self.assertRaises(AssertionError):
loader._get_name_from_path('/bar/baz.py')
def test_find_tests(self):
loader = unittest.TestLoader()
original_listdir = os.listdir
def restore_listdir():
os.listdir = original_listdir
original_isfile = os.path.isfile
def restore_isfile():
os.path.isfile = original_isfile
original_isdir = os.path.isdir
def restore_isdir():
os.path.isdir = original_isdir
path_lists = [['test2.py', 'test1.py', 'not_a_test.py', 'test_dir',
'test.foo', 'test-not-a-module.py', 'another_dir'],
['test4.py', 'test3.py', ]]
os.listdir = lambda path: path_lists.pop(0)
self.addCleanup(restore_listdir)
def isdir(path):
return path.endswith('dir')
os.path.isdir = isdir
self.addCleanup(restore_isdir)
def isfile(path):
# another_dir is not a package and so shouldn't be recursed into
return not path.endswith('dir') and not 'another_dir' in path
os.path.isfile = isfile
self.addCleanup(restore_isfile)
loader._get_module_from_name = lambda path: path + ' module'
orig_load_tests = loader.loadTestsFromModule
def loadTestsFromModule(module, pattern=None):
# This is where load_tests is called.
base = orig_load_tests(module, pattern=pattern)
return base + [module + ' tests']
loader.loadTestsFromModule = loadTestsFromModule
loader.suiteClass = lambda thing: thing
top_level = os.path.abspath('/foo')
loader._top_level_dir = top_level
suite = list(loader._find_tests(top_level, 'test*.py'))
# The test suites found should be sorted alphabetically for reliable
# execution order.
expected = [[name + ' module tests'] for name in
('test1', 'test2', 'test_dir')]
expected.extend([[('test_dir.%s' % name) + ' module tests'] for name in
('test3', 'test4')])
self.assertEqual(suite, expected)
def test_find_tests_socket(self):
# A socket is neither a directory nor a regular file.
# https://bugs.python.org/issue25320
loader = unittest.TestLoader()
original_listdir = os.listdir
def restore_listdir():
os.listdir = original_listdir
original_isfile = os.path.isfile
def restore_isfile():
os.path.isfile = original_isfile
original_isdir = os.path.isdir
def restore_isdir():
os.path.isdir = original_isdir
path_lists = [['socket']]
os.listdir = lambda path: path_lists.pop(0)
self.addCleanup(restore_listdir)
os.path.isdir = lambda path: False
self.addCleanup(restore_isdir)
os.path.isfile = lambda path: False
self.addCleanup(restore_isfile)
loader._get_module_from_name = lambda path: path + ' module'
orig_load_tests = loader.loadTestsFromModule
def loadTestsFromModule(module, pattern=None):
# This is where load_tests is called.
base = orig_load_tests(module, pattern=pattern)
return base + [module + ' tests']
loader.loadTestsFromModule = loadTestsFromModule
loader.suiteClass = lambda thing: thing
top_level = os.path.abspath('/foo')
loader._top_level_dir = top_level
suite = list(loader._find_tests(top_level, 'test*.py'))
self.assertEqual(suite, [])
def test_find_tests_with_package(self):
loader = unittest.TestLoader()
original_listdir = os.listdir
def restore_listdir():
os.listdir = original_listdir
original_isfile = os.path.isfile
def restore_isfile():
os.path.isfile = original_isfile
original_isdir = os.path.isdir
def restore_isdir():
os.path.isdir = original_isdir
directories = ['a_directory', 'test_directory', 'test_directory2']
path_lists = [directories, [], [], []]
os.listdir = lambda path: path_lists.pop(0)
self.addCleanup(restore_listdir)
os.path.isdir = lambda path: True
self.addCleanup(restore_isdir)
os.path.isfile = lambda path: os.path.basename(path) not in directories
self.addCleanup(restore_isfile)
class Module(object):
paths = []
load_tests_args = []
def __init__(self, path):
self.path = path
self.paths.append(path)
if os.path.basename(path) == 'test_directory':
def load_tests(loader, tests, pattern):
self.load_tests_args.append((loader, tests, pattern))
return [self.path + ' load_tests']
self.load_tests = load_tests
def __eq__(self, other):
return self.path == other.path
loader._get_module_from_name = lambda name: Module(name)
orig_load_tests = loader.loadTestsFromModule
def loadTestsFromModule(module, pattern=None):
# This is where load_tests is called.
base = orig_load_tests(module, pattern=pattern)
return base + [module.path + ' module tests']
loader.loadTestsFromModule = loadTestsFromModule
loader.suiteClass = lambda thing: thing
loader._top_level_dir = '/foo'
# this time no '.py' on the pattern so that it can match
# a test package
suite = list(loader._find_tests('/foo', 'test*'))
# We should have loaded tests from the a_directory and test_directory2
# directly and via load_tests for the test_directory package, which
# still calls the baseline module loader.
self.assertEqual(suite,
[['a_directory module tests'],
['test_directory load_tests',
'test_directory module tests'],
['test_directory2 module tests']])
# The test module paths should be sorted for reliable execution order
self.assertEqual(Module.paths,
['a_directory', 'test_directory', 'test_directory2'])
# load_tests should have been called once with loader, tests and pattern
# (but there are no tests in our stub module itself, so that is [] at
# the time of call).
self.assertEqual(Module.load_tests_args,
[(loader, [], 'test*')])
def test_find_tests_default_calls_package_load_tests(self):
loader = unittest.TestLoader()
original_listdir = os.listdir
def restore_listdir():
os.listdir = original_listdir
original_isfile = os.path.isfile
def restore_isfile():
os.path.isfile = original_isfile
original_isdir = os.path.isdir
def restore_isdir():
os.path.isdir = original_isdir
directories = ['a_directory', 'test_directory', 'test_directory2']
path_lists = [directories, [], [], []]
os.listdir = lambda path: path_lists.pop(0)
self.addCleanup(restore_listdir)
os.path.isdir = lambda path: True
self.addCleanup(restore_isdir)
os.path.isfile = lambda path: os.path.basename(path) not in directories
self.addCleanup(restore_isfile)
class Module(object):
paths = []
load_tests_args = []
def __init__(self, path):
self.path = path
self.paths.append(path)
if os.path.basename(path) == 'test_directory':
def load_tests(loader, tests, pattern):
self.load_tests_args.append((loader, tests, pattern))
return [self.path + ' load_tests']
self.load_tests = load_tests
def __eq__(self, other):
return self.path == other.path
loader._get_module_from_name = lambda name: Module(name)
orig_load_tests = loader.loadTestsFromModule
def loadTestsFromModule(module, pattern=None):
# This is where load_tests is called.
base = orig_load_tests(module, pattern=pattern)
return base + [module.path + ' module tests']
loader.loadTestsFromModule = loadTestsFromModule
loader.suiteClass = lambda thing: thing
loader._top_level_dir = '/foo'
# this time no '.py' on the pattern so that it can match
# a test package
suite = list(loader._find_tests('/foo', 'test*.py'))
# We should have loaded tests from the a_directory and test_directory2
# directly and via load_tests for the test_directory package, which
# still calls the baseline module loader.
self.assertEqual(suite,
[['a_directory module tests'],
['test_directory load_tests',
'test_directory module tests'],
['test_directory2 module tests']])
# The test module paths should be sorted for reliable execution order
self.assertEqual(Module.paths,
['a_directory', 'test_directory', 'test_directory2'])
# load_tests should have been called once with loader, tests and pattern
self.assertEqual(Module.load_tests_args,
[(loader, [], 'test*.py')])
def test_find_tests_customize_via_package_pattern(self):
# This test uses the example 'do-nothing' load_tests from
# https://docs.python.org/3/library/unittest.html#load-tests-protocol
# to make sure that that actually works.
# Housekeeping
original_listdir = os.listdir
def restore_listdir():
os.listdir = original_listdir
self.addCleanup(restore_listdir)
original_isfile = os.path.isfile
def restore_isfile():
os.path.isfile = original_isfile
self.addCleanup(restore_isfile)
original_isdir = os.path.isdir
def restore_isdir():
os.path.isdir = original_isdir
self.addCleanup(restore_isdir)
self.addCleanup(sys.path.remove, abspath('/foo'))
# Test data: we expect the following:
# a listdir to find our package, and isfile and isdir checks on it.
# a module-from-name call to turn that into a module
# followed by load_tests.
# then our load_tests will call discover() which is messy
# but that finally chains into find_tests again for the child dir -
# which is why we don't have an infinite loop.
# We expect to see:
# the module load tests for both package and plain module called,
# and the plain module result nested by the package module load_tests
# indicating that it was processed and could have been mutated.
vfs = {abspath('/foo'): ['my_package'],
abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}
def list_dir(path):
return list(vfs[path])
os.listdir = list_dir
os.path.isdir = lambda path: not path.endswith('.py')
os.path.isfile = lambda path: path.endswith('.py')
class Module(object):
paths = []
load_tests_args = []
def __init__(self, path):
self.path = path
self.paths.append(path)
if path.endswith('test_module'):
def load_tests(loader, tests, pattern):
self.load_tests_args.append((loader, tests, pattern))
return [self.path + ' load_tests']
else:
def load_tests(loader, tests, pattern):
self.load_tests_args.append((loader, tests, pattern))
# top level directory cached on loader instance
__file__ = '/foo/my_package/__init__.py'
this_dir = os.path.dirname(__file__)
pkg_tests = loader.discover(
start_dir=this_dir, pattern=pattern)
return [self.path + ' load_tests', tests
] + pkg_tests
self.load_tests = load_tests
def __eq__(self, other):
return self.path == other.path
loader = unittest.TestLoader()
loader._get_module_from_name = lambda name: Module(name)
loader.suiteClass = lambda thing: thing
loader._top_level_dir = abspath('/foo')
# this time no '.py' on the pattern so that it can match
# a test package
suite = list(loader._find_tests(abspath('/foo'), 'test*.py'))
# We should have loaded tests from both my_package and
# my_package.test_module, and also run the load_tests hook in both.
# (normally this would be nested TestSuites.)
self.assertEqual(suite,
[['my_package load_tests', [],
['my_package.test_module load_tests']]])
# Parents before children.
self.assertEqual(Module.paths,
['my_package', 'my_package.test_module'])
# load_tests should have been called twice with loader, tests and pattern
self.assertEqual(Module.load_tests_args,
[(loader, [], 'test*.py'),
(loader, [], 'test*.py')])
def test_discover(self):
loader = unittest.TestLoader()
original_isfile = os.path.isfile
original_isdir = os.path.isdir
def restore_isfile():
os.path.isfile = original_isfile
os.path.isfile = lambda path: False
self.addCleanup(restore_isfile)
orig_sys_path = sys.path[:]
def restore_path():
sys.path[:] = orig_sys_path
self.addCleanup(restore_path)
full_path = os.path.abspath(os.path.normpath('/foo'))
with self.assertRaises(ImportError):
loader.discover('/foo/bar', top_level_dir='/foo')
self.assertEqual(loader._top_level_dir, full_path)
self.assertIn(full_path, sys.path)
os.path.isfile = lambda path: True
os.path.isdir = lambda path: True
def restore_isdir():
os.path.isdir = original_isdir
self.addCleanup(restore_isdir)
_find_tests_args = []
def _find_tests(start_dir, pattern):
_find_tests_args.append((start_dir, pattern))
return ['tests']
loader._find_tests = _find_tests
loader.suiteClass = str
suite = loader.discover('/foo/bar/baz', 'pattern', '/foo/bar')
top_level_dir = os.path.abspath('/foo/bar')
start_dir = os.path.abspath('/foo/bar/baz')
self.assertEqual(suite, "['tests']")
self.assertEqual(loader._top_level_dir, os.path.abspath('/foo'))
self.assertEqual(_find_tests_args, [(start_dir, 'pattern')])
self.assertIn(top_level_dir, sys.path)
def test_discover_should_not_persist_top_level_dir_between_calls(self):
original_isfile = os.path.isfile
original_isdir = os.path.isdir
original_sys_path = sys.path[:]
def restore():
os.path.isfile = original_isfile
os.path.isdir = original_isdir
sys.path[:] = original_sys_path
self.addCleanup(restore)
os.path.isfile = lambda path: True
os.path.isdir = lambda path: True
loader = unittest.TestLoader()
loader.suiteClass = str
dir = '/foo/bar'
top_level_dir = '/foo'
loader.discover(dir, top_level_dir=top_level_dir)
self.assertEqual(loader._top_level_dir, None)
loader._top_level_dir = dir2 = '/previous/dir'
loader.discover(dir, top_level_dir=top_level_dir)
self.assertEqual(loader._top_level_dir, dir2)
def test_discover_start_dir_is_package_calls_package_load_tests(self):
# This test verifies that the package load_tests in a package is indeed
# invoked when the start_dir is a package (and not the top level).
# http://bugs.python.org/issue22457
# Test data: we expect the following:
# an isfile to verify the package, then importing and scanning
# as per _find_tests' normal behaviour.
# We expect to see our load_tests hook called once.
vfs = {abspath('/toplevel'): ['startdir'],
abspath('/toplevel/startdir'): ['__init__.py']}
def list_dir(path):
return list(vfs[path])
self.addCleanup(setattr, os, 'listdir', os.listdir)
os.listdir = list_dir
self.addCleanup(setattr, os.path, 'isfile', os.path.isfile)
os.path.isfile = lambda path: path.endswith('.py')
self.addCleanup(setattr, os.path, 'isdir', os.path.isdir)
os.path.isdir = lambda path: not path.endswith('.py')
self.addCleanup(sys.path.remove, abspath('/toplevel'))
class Module(object):
paths = []
load_tests_args = []
def __init__(self, path):
self.path = path
def load_tests(self, loader, tests, pattern):
return ['load_tests called ' + self.path]
def __eq__(self, other):
return self.path == other.path
loader = unittest.TestLoader()
loader._get_module_from_name = lambda name: Module(name)
loader.suiteClass = lambda thing: thing
suite = loader.discover('/toplevel/startdir', top_level_dir='/toplevel')
# We should have loaded tests from the package __init__.
# (normally this would be nested TestSuites.)
self.assertEqual(suite,
[['load_tests called startdir']])
def setup_import_issue_tests(self, fakefile):
listdir = os.listdir
os.listdir = lambda _: [fakefile]
isfile = os.path.isfile
os.path.isfile = lambda _: True
orig_sys_path = sys.path[:]
def restore():
os.path.isfile = isfile
os.listdir = listdir
sys.path[:] = orig_sys_path
self.addCleanup(restore)
def setup_import_issue_package_tests(self, vfs):
self.addCleanup(setattr, os, 'listdir', os.listdir)
self.addCleanup(setattr, os.path, 'isfile', os.path.isfile)
self.addCleanup(setattr, os.path, 'isdir', os.path.isdir)
self.addCleanup(sys.path.__setitem__, slice(None), list(sys.path))
def list_dir(path):
return list(vfs[path])
os.listdir = list_dir
os.path.isdir = lambda path: not path.endswith('.py')
os.path.isfile = lambda path: path.endswith('.py')
def test_discover_with_modules_that_fail_to_import(self):
loader = unittest.TestLoader()
self.setup_import_issue_tests('test_this_does_not_exist.py')
suite = loader.discover('.')
self.assertIn(os.getcwd(), sys.path)
self.assertEqual(suite.countTestCases(), 1)
# Errors loading the suite are also captured for introspection.
self.assertNotEqual([], loader.errors)
self.assertEqual(1, len(loader.errors))
error = loader.errors[0]
self.assertTrue(
'Failed to import test module: test_this_does_not_exist' in error,
'missing error string in %r' % error)
test = list(list(suite)[0])[0] # extract test from suite
with self.assertRaises(ImportError):
test.test_this_does_not_exist()
def test_discover_with_init_modules_that_fail_to_import(self):
vfs = {abspath('/foo'): ['my_package'],
abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}
self.setup_import_issue_package_tests(vfs)
import_calls = []
def _get_module_from_name(name):
import_calls.append(name)
raise ImportError("Cannot import Name")
loader = unittest.TestLoader()
loader._get_module_from_name = _get_module_from_name
suite = loader.discover(abspath('/foo'))
self.assertIn(abspath('/foo'), sys.path)
self.assertEqual(suite.countTestCases(), 1)
# Errors loading the suite are also captured for introspection.
self.assertNotEqual([], loader.errors)
self.assertEqual(1, len(loader.errors))
error = loader.errors[0]
self.assertTrue(
'Failed to import test module: my_package' in error,
'missing error string in %r' % error)
test = list(list(suite)[0])[0] # extract test from suite
with self.assertRaises(ImportError):
test.my_package()
self.assertEqual(import_calls, ['my_package'])
# Check picklability
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
pickle.loads(pickle.dumps(test, proto))
def test_discover_with_module_that_raises_SkipTest_on_import(self):
if not unittest.BaseTestSuite._cleanup:
raise unittest.SkipTest("Suite cleanup is disabled")
loader = unittest.TestLoader()
def _get_module_from_name(name):
raise unittest.SkipTest('skipperoo')
loader._get_module_from_name = _get_module_from_name
self.setup_import_issue_tests('test_skip_dummy.py')
suite = loader.discover('.')
self.assertEqual(suite.countTestCases(), 1)
result = unittest.TestResult()
suite.run(result)
self.assertEqual(len(result.skipped), 1)
# Check picklability
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
pickle.loads(pickle.dumps(suite, proto))
def test_discover_with_init_module_that_raises_SkipTest_on_import(self):
if not unittest.BaseTestSuite._cleanup:
raise unittest.SkipTest("Suite cleanup is disabled")
vfs = {abspath('/foo'): ['my_package'],
abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}
self.setup_import_issue_package_tests(vfs)
import_calls = []
def _get_module_from_name(name):
import_calls.append(name)
raise unittest.SkipTest('skipperoo')
loader = unittest.TestLoader()
loader._get_module_from_name = _get_module_from_name
suite = loader.discover(abspath('/foo'))
self.assertIn(abspath('/foo'), sys.path)
self.assertEqual(suite.countTestCases(), 1)
result = unittest.TestResult()
suite.run(result)
self.assertEqual(len(result.skipped), 1)
self.assertEqual(result.testsRun, 1)
self.assertEqual(import_calls, ['my_package'])
# Check picklability
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
pickle.loads(pickle.dumps(suite, proto))
def test_command_line_handling_parseArgs(self):
program = TestableTestProgram()
args = []
program._do_discovery = args.append
program.parseArgs(['something', 'discover'])
self.assertEqual(args, [[]])
args[:] = []
program.parseArgs(['something', 'discover', 'foo', 'bar'])
self.assertEqual(args, [['foo', 'bar']])
def test_command_line_handling_discover_by_default(self):
program = TestableTestProgram()
args = []
program._do_discovery = args.append
program.parseArgs(['something'])
self.assertEqual(args, [[]])
self.assertEqual(program.verbosity, 1)
self.assertIs(program.buffer, False)
self.assertIs(program.catchbreak, False)
self.assertIs(program.failfast, False)
def test_command_line_handling_discover_by_default_with_options(self):
program = TestableTestProgram()
args = []
program._do_discovery = args.append
program.parseArgs(['something', '-v', '-b', '-v', '-c', '-f'])
self.assertEqual(args, [[]])
self.assertEqual(program.verbosity, 2)
self.assertIs(program.buffer, True)
self.assertIs(program.catchbreak, True)
self.assertIs(program.failfast, True)
def test_command_line_handling_do_discovery_too_many_arguments(self):
program = TestableTestProgram()
program.testLoader = None
with support.captured_stderr() as stderr, \
self.assertRaises(SystemExit) as cm:
# too many args
program._do_discovery(['one', 'two', 'three', 'four'])
self.assertEqual(cm.exception.args, (2,))
self.assertIn('usage:', stderr.getvalue())
def test_command_line_handling_do_discovery_uses_default_loader(self):
program = object.__new__(unittest.TestProgram)
program._initArgParsers()
class Loader(object):
args = []
def discover(self, start_dir, pattern, top_level_dir):
self.args.append((start_dir, pattern, top_level_dir))
return 'tests'
program.testLoader = Loader()
program._do_discovery(['-v'])
self.assertEqual(Loader.args, [('.', 'test*.py', None)])
def test_command_line_handling_do_discovery_calls_loader(self):
program = TestableTestProgram()
class Loader(object):
args = []
def discover(self, start_dir, pattern, top_level_dir):
self.args.append((start_dir, pattern, top_level_dir))
return 'tests'
program._do_discovery(['-v'], Loader=Loader)
self.assertEqual(program.verbosity, 2)
self.assertEqual(program.test, 'tests')
self.assertEqual(Loader.args, [('.', 'test*.py', None)])
Loader.args = []
program = TestableTestProgram()
program._do_discovery(['--verbose'], Loader=Loader)
self.assertEqual(program.test, 'tests')
self.assertEqual(Loader.args, [('.', 'test*.py', None)])
Loader.args = []
program = TestableTestProgram()
program._do_discovery([], Loader=Loader)
self.assertEqual(program.test, 'tests')
self.assertEqual(Loader.args, [('.', 'test*.py', None)])
Loader.args = []
program = TestableTestProgram()
program._do_discovery(['fish'], Loader=Loader)
self.assertEqual(program.test, 'tests')
self.assertEqual(Loader.args, [('fish', 'test*.py', None)])
Loader.args = []
program = TestableTestProgram()
program._do_discovery(['fish', 'eggs'], Loader=Loader)
self.assertEqual(program.test, 'tests')
self.assertEqual(Loader.args, [('fish', 'eggs', None)])
Loader.args = []
program = TestableTestProgram()
program._do_discovery(['fish', 'eggs', 'ham'], Loader=Loader)
self.assertEqual(program.test, 'tests')
self.assertEqual(Loader.args, [('fish', 'eggs', 'ham')])
Loader.args = []
program = TestableTestProgram()
program._do_discovery(['-s', 'fish'], Loader=Loader)
self.assertEqual(program.test, 'tests')
self.assertEqual(Loader.args, [('fish', 'test*.py', None)])
Loader.args = []
program = TestableTestProgram()
program._do_discovery(['-t', 'fish'], Loader=Loader)
self.assertEqual(program.test, 'tests')
self.assertEqual(Loader.args, [('.', 'test*.py', 'fish')])
Loader.args = []
program = TestableTestProgram()
program._do_discovery(['-p', 'fish'], Loader=Loader)
self.assertEqual(program.test, 'tests')
self.assertEqual(Loader.args, [('.', 'fish', None)])
self.assertFalse(program.failfast)
self.assertFalse(program.catchbreak)
Loader.args = []
program = TestableTestProgram()
program._do_discovery(['-p', 'eggs', '-s', 'fish', '-v', '-f', '-c'],
Loader=Loader)
self.assertEqual(program.test, 'tests')
self.assertEqual(Loader.args, [('fish', 'eggs', None)])
self.assertEqual(program.verbosity, 2)
self.assertTrue(program.failfast)
self.assertTrue(program.catchbreak)
def setup_module_clash(self):
class Module(object):
__file__ = 'bar/foo.py'
sys.modules['foo'] = Module
full_path = os.path.abspath('foo')
original_listdir = os.listdir
original_isfile = os.path.isfile
original_isdir = os.path.isdir
original_realpath = os.path.realpath
def cleanup():
os.listdir = original_listdir
os.path.isfile = original_isfile
os.path.isdir = original_isdir
os.path.realpath = original_realpath
del sys.modules['foo']
if full_path in sys.path:
sys.path.remove(full_path)
self.addCleanup(cleanup)
def listdir(_):
return ['foo.py']
def isfile(_):
return True
def isdir(_):
return True
os.listdir = listdir
os.path.isfile = isfile
os.path.isdir = isdir
if os.name == 'nt':
# ntpath.realpath may inject path prefixes when failing to
# resolve real files, so we substitute abspath() here instead.
os.path.realpath = os.path.abspath
return full_path
def test_detect_module_clash(self):
full_path = self.setup_module_clash()
loader = unittest.TestLoader()
mod_dir = os.path.abspath('bar')
expected_dir = os.path.abspath('foo')
msg = re.escape(r"'foo' module incorrectly imported from %r. Expected %r. "
"Is this module globally installed?" % (mod_dir, expected_dir))
self.assertRaisesRegex(
ImportError, '^%s$' % msg, loader.discover,
start_dir='foo', pattern='foo.py'
)
self.assertEqual(sys.path[0], full_path)
def test_module_symlink_ok(self):
full_path = self.setup_module_clash()
original_realpath = os.path.realpath
mod_dir = os.path.abspath('bar')
expected_dir = os.path.abspath('foo')
def cleanup():
os.path.realpath = original_realpath
self.addCleanup(cleanup)
def realpath(path):
if path == os.path.join(mod_dir, 'foo.py'):
return os.path.join(expected_dir, 'foo.py')
return path
os.path.realpath = realpath
loader = unittest.TestLoader()
loader.discover(start_dir='foo', pattern='foo.py')
def test_discovery_from_dotted_path(self):
loader = unittest.TestLoader()
tests = [self]
expectedPath = os.path.abspath(os.path.dirname(test.test_unittest.__file__))
self.wasRun = False
def _find_tests(start_dir, pattern):
self.wasRun = True
self.assertEqual(start_dir, expectedPath)
return tests
loader._find_tests = _find_tests
suite = loader.discover('test.test_unittest')
self.assertTrue(self.wasRun)
self.assertEqual(suite._tests, tests)
def test_discovery_from_dotted_path_builtin_modules(self):
loader = unittest.TestLoader()
listdir = os.listdir
os.listdir = lambda _: ['test_this_does_not_exist.py']
isfile = os.path.isfile
isdir = os.path.isdir
os.path.isdir = lambda _: False
orig_sys_path = sys.path[:]
def restore():
os.path.isfile = isfile
os.path.isdir = isdir
os.listdir = listdir
sys.path[:] = orig_sys_path
self.addCleanup(restore)
with self.assertRaises(TypeError) as cm:
loader.discover('sys')
self.assertEqual(str(cm.exception),
'Can not use builtin modules '
'as dotted module names')
def test_discovery_failed_discovery(self):
from test.test_importlib import util
loader = unittest.TestLoader()
package = types.ModuleType('package')
def _import(packagename, *args, **kwargs):
sys.modules[packagename] = package
return package
with unittest.mock.patch('builtins.__import__', _import):
# Since loader.discover() can modify sys.path, restore it when done.
with import_helper.DirsOnSysPath():
# Make sure to remove 'package' from sys.modules when done.
with util.uncache('package'):
with self.assertRaises(TypeError) as cm:
loader.discover('package')
self.assertEqual(str(cm.exception),
'don\'t know how to discover from {!r}'
.format(package))
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,148 @@
import unittest
from test.test_unittest.support import LoggingResult
class Test_FunctionTestCase(unittest.TestCase):
# "Return the number of tests represented by the this test object. For
# TestCase instances, this will always be 1"
def test_countTestCases(self):
test = unittest.FunctionTestCase(lambda: None)
self.assertEqual(test.countTestCases(), 1)
# "When a setUp() method is defined, the test runner will run that method
# prior to each test. Likewise, if a tearDown() method is defined, the
# test runner will invoke that method after each test. In the example,
# setUp() was used to create a fresh sequence for each test."
#
# Make sure the proper call order is maintained, even if setUp() raises
# an exception.
def test_run_call_order__error_in_setUp(self):
events = []
result = LoggingResult(events)
def setUp():
events.append('setUp')
raise RuntimeError('raised by setUp')
def test():
events.append('test')
def tearDown():
events.append('tearDown')
expected = ['startTest', 'setUp', 'addError', 'stopTest']
unittest.FunctionTestCase(test, setUp, tearDown).run(result)
self.assertEqual(events, expected)
# "When a setUp() method is defined, the test runner will run that method
# prior to each test. Likewise, if a tearDown() method is defined, the
# test runner will invoke that method after each test. In the example,
# setUp() was used to create a fresh sequence for each test."
#
# Make sure the proper call order is maintained, even if the test raises
# an error (as opposed to a failure).
def test_run_call_order__error_in_test(self):
events = []
result = LoggingResult(events)
def setUp():
events.append('setUp')
def test():
events.append('test')
raise RuntimeError('raised by test')
def tearDown():
events.append('tearDown')
expected = ['startTest', 'setUp', 'test',
'addError', 'tearDown', 'stopTest']
unittest.FunctionTestCase(test, setUp, tearDown).run(result)
self.assertEqual(events, expected)
# "When a setUp() method is defined, the test runner will run that method
# prior to each test. Likewise, if a tearDown() method is defined, the
# test runner will invoke that method after each test. In the example,
# setUp() was used to create a fresh sequence for each test."
#
# Make sure the proper call order is maintained, even if the test signals
# a failure (as opposed to an error).
def test_run_call_order__failure_in_test(self):
events = []
result = LoggingResult(events)
def setUp():
events.append('setUp')
def test():
events.append('test')
self.fail('raised by test')
def tearDown():
events.append('tearDown')
expected = ['startTest', 'setUp', 'test',
'addFailure', 'tearDown', 'stopTest']
unittest.FunctionTestCase(test, setUp, tearDown).run(result)
self.assertEqual(events, expected)
# "When a setUp() method is defined, the test runner will run that method
# prior to each test. Likewise, if a tearDown() method is defined, the
# test runner will invoke that method after each test. In the example,
# setUp() was used to create a fresh sequence for each test."
#
# Make sure the proper call order is maintained, even if tearDown() raises
# an exception.
def test_run_call_order__error_in_tearDown(self):
events = []
result = LoggingResult(events)
def setUp():
events.append('setUp')
def test():
events.append('test')
def tearDown():
events.append('tearDown')
raise RuntimeError('raised by tearDown')
expected = ['startTest', 'setUp', 'test', 'tearDown', 'addError',
'stopTest']
unittest.FunctionTestCase(test, setUp, tearDown).run(result)
self.assertEqual(events, expected)
# "Return a string identifying the specific test case."
#
# Because of the vague nature of the docs, I'm not going to lock this
# test down too much. Really all that can be asserted is that the id()
# will be a string (either 8-byte or unicode -- again, because the docs
# just say "string")
def test_id(self):
test = unittest.FunctionTestCase(lambda: None)
self.assertIsInstance(test.id(), str)
# "Returns a one-line description of the test, or None if no description
# has been provided. The default implementation of this method returns
# the first line of the test method's docstring, if available, or None."
def test_shortDescription__no_docstring(self):
test = unittest.FunctionTestCase(lambda: None)
self.assertEqual(test.shortDescription(), None)
# "Returns a one-line description of the test, or None if no description
# has been provided. The default implementation of this method returns
# the first line of the test method's docstring, if available, or None."
def test_shortDescription__singleline_docstring(self):
desc = "this tests foo"
test = unittest.FunctionTestCase(lambda: None, description=desc)
self.assertEqual(test.shortDescription(), "this tests foo")
if __name__ == "__main__":
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,510 @@
import os
import sys
import subprocess
from test import support
import unittest
import test.test_unittest
from test.test_unittest.test_result import BufferedWriter
@support.force_not_colorized_test_class
class Test_TestProgram(unittest.TestCase):
def test_discovery_from_dotted_path(self):
loader = unittest.TestLoader()
tests = [self]
expectedPath = os.path.abspath(os.path.dirname(test.test_unittest.__file__))
self.wasRun = False
def _find_tests(start_dir, pattern):
self.wasRun = True
self.assertEqual(start_dir, expectedPath)
return tests
loader._find_tests = _find_tests
suite = loader.discover('test.test_unittest')
self.assertTrue(self.wasRun)
self.assertEqual(suite._tests, tests)
# Horrible white box test
def testNoExit(self):
result = object()
test = object()
class FakeRunner(object):
def run(self, test):
self.test = test
return result
runner = FakeRunner()
oldParseArgs = unittest.TestProgram.parseArgs
def restoreParseArgs():
unittest.TestProgram.parseArgs = oldParseArgs
unittest.TestProgram.parseArgs = lambda *args: None
self.addCleanup(restoreParseArgs)
def removeTest():
del unittest.TestProgram.test
unittest.TestProgram.test = test
self.addCleanup(removeTest)
program = unittest.TestProgram(testRunner=runner, exit=False, verbosity=2)
self.assertEqual(program.result, result)
self.assertEqual(runner.test, test)
self.assertEqual(program.verbosity, 2)
class FooBar(unittest.TestCase):
def testPass(self):
pass
def testFail(self):
raise AssertionError
def testError(self):
1/0
@unittest.skip('skipping')
def testSkipped(self):
raise AssertionError
@unittest.expectedFailure
def testExpectedFailure(self):
raise AssertionError
@unittest.expectedFailure
def testUnexpectedSuccess(self):
pass
class Empty(unittest.TestCase):
pass
class TestLoader(unittest.TestLoader):
"""Test loader that returns a suite containing the supplied testcase."""
def __init__(self, testcase):
self.testcase = testcase
def loadTestsFromModule(self, module):
return self.suiteClass(
[self.loadTestsFromTestCase(self.testcase)])
def loadTestsFromNames(self, names, module):
return self.suiteClass(
[self.loadTestsFromTestCase(self.testcase)])
def test_defaultTest_with_string(self):
class FakeRunner(object):
def run(self, test):
self.test = test
return True
old_argv = sys.argv
sys.argv = ['faketest']
runner = FakeRunner()
program = unittest.TestProgram(testRunner=runner, exit=False,
defaultTest='test.test_unittest',
testLoader=self.TestLoader(self.FooBar))
sys.argv = old_argv
self.assertEqual(('test.test_unittest',), program.testNames)
def test_defaultTest_with_iterable(self):
class FakeRunner(object):
def run(self, test):
self.test = test
return True
old_argv = sys.argv
sys.argv = ['faketest']
runner = FakeRunner()
program = unittest.TestProgram(
testRunner=runner, exit=False,
defaultTest=['test.test_unittest', 'test.test_unittest2'],
testLoader=self.TestLoader(self.FooBar))
sys.argv = old_argv
self.assertEqual(['test.test_unittest', 'test.test_unittest2'],
program.testNames)
def test_NonExit(self):
stream = BufferedWriter()
program = unittest.main(exit=False,
argv=["foobar"],
testRunner=unittest.TextTestRunner(stream=stream),
testLoader=self.TestLoader(self.FooBar))
self.assertTrue(hasattr(program, 'result'))
out = stream.getvalue()
self.assertIn('\nFAIL: testFail ', out)
self.assertIn('\nERROR: testError ', out)
self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out)
expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, '
'expected failures=1, unexpected successes=1)\n')
self.assertTrue(out.endswith(expected))
def test_Exit(self):
stream = BufferedWriter()
with self.assertRaises(SystemExit) as cm:
unittest.main(
argv=["foobar"],
testRunner=unittest.TextTestRunner(stream=stream),
exit=True,
testLoader=self.TestLoader(self.FooBar))
self.assertEqual(cm.exception.code, 1)
out = stream.getvalue()
self.assertIn('\nFAIL: testFail ', out)
self.assertIn('\nERROR: testError ', out)
self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out)
expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, '
'expected failures=1, unexpected successes=1)\n')
self.assertTrue(out.endswith(expected))
def test_ExitAsDefault(self):
stream = BufferedWriter()
with self.assertRaises(SystemExit):
unittest.main(
argv=["foobar"],
testRunner=unittest.TextTestRunner(stream=stream),
testLoader=self.TestLoader(self.FooBar))
out = stream.getvalue()
self.assertIn('\nFAIL: testFail ', out)
self.assertIn('\nERROR: testError ', out)
self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out)
expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, '
'expected failures=1, unexpected successes=1)\n')
self.assertTrue(out.endswith(expected))
def test_ExitSkippedSuite(self):
stream = BufferedWriter()
with self.assertRaises(SystemExit) as cm:
unittest.main(
argv=["foobar", "-k", "testSkipped"],
testRunner=unittest.TextTestRunner(stream=stream),
testLoader=self.TestLoader(self.FooBar))
self.assertEqual(cm.exception.code, 0)
out = stream.getvalue()
expected = '\n\nOK (skipped=1)\n'
self.assertTrue(out.endswith(expected))
def test_ExitEmptySuite(self):
stream = BufferedWriter()
with self.assertRaises(SystemExit) as cm:
unittest.main(
argv=["empty"],
testRunner=unittest.TextTestRunner(stream=stream),
testLoader=self.TestLoader(self.Empty))
self.assertEqual(cm.exception.code, 5)
out = stream.getvalue()
self.assertIn('\nNO TESTS RAN\n', out)
class InitialisableProgram(unittest.TestProgram):
exit = False
result = None
verbosity = 1
defaultTest = None
tb_locals = False
testRunner = None
testLoader = unittest.defaultTestLoader
module = '__main__'
progName = 'test'
test = 'test'
def __init__(self, *args):
pass
RESULT = object()
class FakeRunner(object):
initArgs = None
test = None
raiseError = 0
def __init__(self, **kwargs):
FakeRunner.initArgs = kwargs
if FakeRunner.raiseError:
FakeRunner.raiseError -= 1
raise TypeError
def run(self, test):
FakeRunner.test = test
return RESULT
@support.requires_subprocess()
class TestCommandLineArgs(unittest.TestCase):
def setUp(self):
self.program = InitialisableProgram()
self.program.createTests = lambda: None
FakeRunner.initArgs = None
FakeRunner.test = None
FakeRunner.raiseError = 0
def testVerbosity(self):
program = self.program
for opt in '-q', '--quiet':
program.verbosity = 1
program.parseArgs([None, opt])
self.assertEqual(program.verbosity, 0)
for opt in '-v', '--verbose':
program.verbosity = 1
program.parseArgs([None, opt])
self.assertEqual(program.verbosity, 2)
def testBufferCatchFailfast(self):
program = self.program
for arg, attr in (('buffer', 'buffer'), ('failfast', 'failfast'),
('catch', 'catchbreak')):
setattr(program, attr, None)
program.parseArgs([None])
self.assertIs(getattr(program, attr), False)
false = []
setattr(program, attr, false)
program.parseArgs([None])
self.assertIs(getattr(program, attr), false)
true = [42]
setattr(program, attr, true)
program.parseArgs([None])
self.assertIs(getattr(program, attr), true)
short_opt = '-%s' % arg[0]
long_opt = '--%s' % arg
for opt in short_opt, long_opt:
setattr(program, attr, None)
program.parseArgs([None, opt])
self.assertIs(getattr(program, attr), True)
setattr(program, attr, False)
with support.captured_stderr() as stderr, \
self.assertRaises(SystemExit) as cm:
program.parseArgs([None, opt])
self.assertEqual(cm.exception.args, (2,))
setattr(program, attr, True)
with support.captured_stderr() as stderr, \
self.assertRaises(SystemExit) as cm:
program.parseArgs([None, opt])
self.assertEqual(cm.exception.args, (2,))
def testWarning(self):
"""Test the warnings argument"""
# see #10535
class FakeTP(unittest.TestProgram):
def parseArgs(self, *args, **kw): pass
def runTests(self, *args, **kw): pass
warnoptions = sys.warnoptions[:]
try:
sys.warnoptions[:] = []
# no warn options, no arg -> default
self.assertEqual(FakeTP().warnings, 'default')
# no warn options, w/ arg -> arg value
self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
sys.warnoptions[:] = ['somevalue']
# warn options, no arg -> None
# warn options, w/ arg -> arg value
self.assertEqual(FakeTP().warnings, None)
self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
finally:
sys.warnoptions[:] = warnoptions
def testRunTestsRunnerClass(self):
program = self.program
program.testRunner = FakeRunner
program.verbosity = 'verbosity'
program.failfast = 'failfast'
program.buffer = 'buffer'
program.warnings = 'warnings'
program.durations = '5'
program.runTests()
self.assertEqual(FakeRunner.initArgs, {'verbosity': 'verbosity',
'failfast': 'failfast',
'buffer': 'buffer',
'tb_locals': False,
'warnings': 'warnings',
'durations': '5'})
self.assertEqual(FakeRunner.test, 'test')
self.assertIs(program.result, RESULT)
def testRunTestsRunnerInstance(self):
program = self.program
program.testRunner = FakeRunner()
FakeRunner.initArgs = None
program.runTests()
# A new FakeRunner should not have been instantiated
self.assertIsNone(FakeRunner.initArgs)
self.assertEqual(FakeRunner.test, 'test')
self.assertIs(program.result, RESULT)
def test_locals(self):
program = self.program
program.testRunner = FakeRunner
program.parseArgs([None, '--locals'])
self.assertEqual(True, program.tb_locals)
program.runTests()
self.assertEqual(FakeRunner.initArgs, {'buffer': False,
'failfast': False,
'tb_locals': True,
'verbosity': 1,
'warnings': None,
'durations': None})
def testRunTestsOldRunnerClass(self):
program = self.program
# Two TypeErrors are needed to fall all the way back to old-style
# runners - one to fail tb_locals, one to fail buffer etc.
FakeRunner.raiseError = 2
program.testRunner = FakeRunner
program.verbosity = 'verbosity'
program.failfast = 'failfast'
program.buffer = 'buffer'
program.test = 'test'
program.durations = '0'
program.runTests()
# If initialising raises a type error it should be retried
# without the new keyword arguments
self.assertEqual(FakeRunner.initArgs, {})
self.assertEqual(FakeRunner.test, 'test')
self.assertIs(program.result, RESULT)
def testCatchBreakInstallsHandler(self):
module = sys.modules['unittest.main']
original = module.installHandler
def restore():
module.installHandler = original
self.addCleanup(restore)
self.installed = False
def fakeInstallHandler():
self.installed = True
module.installHandler = fakeInstallHandler
program = self.program
program.catchbreak = True
program.durations = None
program.testRunner = FakeRunner
program.runTests()
self.assertTrue(self.installed)
def _patch_isfile(self, names, exists=True):
def isfile(path):
return path in names
original = os.path.isfile
os.path.isfile = isfile
def restore():
os.path.isfile = original
self.addCleanup(restore)
def testParseArgsFileNames(self):
# running tests with filenames instead of module names
program = self.program
argv = ['progname', 'foo.py', 'bar.Py', 'baz.PY', 'wing.txt']
self._patch_isfile(argv)
program.createTests = lambda: None
program.parseArgs(argv)
# note that 'wing.txt' is not a Python file so the name should
# *not* be converted to a module name
expected = ['foo', 'bar', 'baz', 'wing.txt']
self.assertEqual(program.testNames, expected)
def testParseArgsFilePaths(self):
program = self.program
argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
self._patch_isfile(argv)
program.createTests = lambda: None
program.parseArgs(argv)
expected = ['foo.bar.baz', 'green.red']
self.assertEqual(program.testNames, expected)
def testParseArgsNonExistentFiles(self):
program = self.program
argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
self._patch_isfile([])
program.createTests = lambda: None
program.parseArgs(argv)
self.assertEqual(program.testNames, argv[1:])
def testParseArgsAbsolutePathsThatCanBeConverted(self):
cur_dir = os.getcwd()
program = self.program
def _join(name):
return os.path.join(cur_dir, name)
argv = ['progname', _join('foo/bar/baz.py'), _join('green\\red.py')]
self._patch_isfile(argv)
program.createTests = lambda: None
program.parseArgs(argv)
expected = ['foo.bar.baz', 'green.red']
self.assertEqual(program.testNames, expected)
def testParseArgsAbsolutePathsThatCannotBeConverted(self):
program = self.program
drive = os.path.splitdrive(os.getcwd())[0]
argv = ['progname', f'{drive}/foo/bar/baz.py', f'{drive}/green/red.py']
self._patch_isfile(argv)
program.createTests = lambda: None
program.parseArgs(argv)
self.assertEqual(program.testNames, argv[1:])
# it may be better to use platform specific functions to normalise paths
# rather than accepting '.PY' and '\' as file separator on Linux / Mac
# it would also be better to check that a filename is a valid module
# identifier (we have a regex for this in loader.py)
# for invalid filenames should we raise a useful error rather than
# leaving the current error message (import of filename fails) in place?
def testParseArgsSelectedTestNames(self):
program = self.program
argv = ['progname', '-k', 'foo', '-k', 'bar', '-k', '*pat*']
program.createTests = lambda: None
program.parseArgs(argv)
self.assertEqual(program.testNamePatterns, ['*foo*', '*bar*', '*pat*'])
def testSelectedTestNamesFunctionalTest(self):
def run_unittest(args):
# Use -E to ignore PYTHONSAFEPATH env var
cmd = [sys.executable, '-E', '-m', 'unittest'] + args
p = subprocess.Popen(cmd,
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, cwd=os.path.dirname(__file__))
with p:
_, stderr = p.communicate()
return stderr.decode()
t = '_test_warnings'
self.assertIn('Ran 5 tests', run_unittest([t]))
self.assertIn('Ran 5 tests', run_unittest(['-k', 'TestWarnings', t]))
self.assertIn('Ran 5 tests', run_unittest(['discover', '-p', '*_test*', '-k', 'TestWarnings']))
self.assertIn('Ran 1 test ', run_unittest(['-k', 'f', t]))
self.assertIn('Ran 5 tests', run_unittest(['-k', 't', t]))
self.assertIn('Ran 2 tests', run_unittest(['-k', '*t', 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]))
if __name__ == '__main__':
unittest.main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,507 @@
import io
import sys
import unittest
def resultFactory(*_):
return unittest.TestResult()
class TestSetups(unittest.TestCase):
def getRunner(self):
return unittest.TextTestRunner(resultclass=resultFactory,
stream=io.StringIO())
def runTests(self, *cases):
suite = unittest.TestSuite()
for case in cases:
tests = unittest.defaultTestLoader.loadTestsFromTestCase(case)
suite.addTests(tests)
runner = self.getRunner()
# creating a nested suite exposes some potential bugs
realSuite = unittest.TestSuite()
realSuite.addTest(suite)
# adding empty suites to the end exposes potential bugs
suite.addTest(unittest.TestSuite())
realSuite.addTest(unittest.TestSuite())
return runner.run(realSuite)
def test_setup_class(self):
class Test(unittest.TestCase):
setUpCalled = 0
@classmethod
def setUpClass(cls):
Test.setUpCalled += 1
unittest.TestCase.setUpClass()
def test_one(self):
pass
def test_two(self):
pass
result = self.runTests(Test)
self.assertEqual(Test.setUpCalled, 1)
self.assertEqual(result.testsRun, 2)
self.assertEqual(len(result.errors), 0)
def test_teardown_class(self):
class Test(unittest.TestCase):
tearDownCalled = 0
@classmethod
def tearDownClass(cls):
Test.tearDownCalled += 1
unittest.TestCase.tearDownClass()
def test_one(self):
pass
def test_two(self):
pass
result = self.runTests(Test)
self.assertEqual(Test.tearDownCalled, 1)
self.assertEqual(result.testsRun, 2)
self.assertEqual(len(result.errors), 0)
def test_teardown_class_two_classes(self):
class Test(unittest.TestCase):
tearDownCalled = 0
@classmethod
def tearDownClass(cls):
Test.tearDownCalled += 1
unittest.TestCase.tearDownClass()
def test_one(self):
pass
def test_two(self):
pass
class Test2(unittest.TestCase):
tearDownCalled = 0
@classmethod
def tearDownClass(cls):
Test2.tearDownCalled += 1
unittest.TestCase.tearDownClass()
def test_one(self):
pass
def test_two(self):
pass
result = self.runTests(Test, Test2)
self.assertEqual(Test.tearDownCalled, 1)
self.assertEqual(Test2.tearDownCalled, 1)
self.assertEqual(result.testsRun, 4)
self.assertEqual(len(result.errors), 0)
def test_error_in_setupclass(self):
class BrokenTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
raise TypeError('foo')
def test_one(self):
pass
def test_two(self):
pass
result = self.runTests(BrokenTest)
self.assertEqual(result.testsRun, 0)
self.assertEqual(len(result.errors), 1)
error, _ = result.errors[0]
self.assertEqual(str(error),
'setUpClass (%s.%s)' % (__name__, BrokenTest.__qualname__))
def test_error_in_teardown_class(self):
class Test(unittest.TestCase):
tornDown = 0
@classmethod
def tearDownClass(cls):
Test.tornDown += 1
raise TypeError('foo')
def test_one(self):
pass
def test_two(self):
pass
class Test2(unittest.TestCase):
tornDown = 0
@classmethod
def tearDownClass(cls):
Test2.tornDown += 1
raise TypeError('foo')
def test_one(self):
pass
def test_two(self):
pass
result = self.runTests(Test, Test2)
self.assertEqual(result.testsRun, 4)
self.assertEqual(len(result.errors), 2)
self.assertEqual(Test.tornDown, 1)
self.assertEqual(Test2.tornDown, 1)
error, _ = result.errors[0]
self.assertEqual(str(error),
'tearDownClass (%s.%s)' % (__name__, Test.__qualname__))
def test_class_not_torndown_when_setup_fails(self):
class Test(unittest.TestCase):
tornDown = False
@classmethod
def setUpClass(cls):
raise TypeError
@classmethod
def tearDownClass(cls):
Test.tornDown = True
raise TypeError('foo')
def test_one(self):
pass
self.runTests(Test)
self.assertFalse(Test.tornDown)
def test_class_not_setup_or_torndown_when_skipped(self):
class Test(unittest.TestCase):
classSetUp = False
tornDown = False
@classmethod
def setUpClass(cls):
Test.classSetUp = True
@classmethod
def tearDownClass(cls):
Test.tornDown = True
def test_one(self):
pass
Test = unittest.skip("hop")(Test)
self.runTests(Test)
self.assertFalse(Test.classSetUp)
self.assertFalse(Test.tornDown)
def test_setup_teardown_order_with_pathological_suite(self):
results = []
class Module1(object):
@staticmethod
def setUpModule():
results.append('Module1.setUpModule')
@staticmethod
def tearDownModule():
results.append('Module1.tearDownModule')
class Module2(object):
@staticmethod
def setUpModule():
results.append('Module2.setUpModule')
@staticmethod
def tearDownModule():
results.append('Module2.tearDownModule')
class Test1(unittest.TestCase):
@classmethod
def setUpClass(cls):
results.append('setup 1')
@classmethod
def tearDownClass(cls):
results.append('teardown 1')
def testOne(self):
results.append('Test1.testOne')
def testTwo(self):
results.append('Test1.testTwo')
class Test2(unittest.TestCase):
@classmethod
def setUpClass(cls):
results.append('setup 2')
@classmethod
def tearDownClass(cls):
results.append('teardown 2')
def testOne(self):
results.append('Test2.testOne')
def testTwo(self):
results.append('Test2.testTwo')
class Test3(unittest.TestCase):
@classmethod
def setUpClass(cls):
results.append('setup 3')
@classmethod
def tearDownClass(cls):
results.append('teardown 3')
def testOne(self):
results.append('Test3.testOne')
def testTwo(self):
results.append('Test3.testTwo')
Test1.__module__ = Test2.__module__ = 'Module'
Test3.__module__ = 'Module2'
sys.modules['Module'] = Module1
sys.modules['Module2'] = Module2
first = unittest.TestSuite((Test1('testOne'),))
second = unittest.TestSuite((Test1('testTwo'),))
third = unittest.TestSuite((Test2('testOne'),))
fourth = unittest.TestSuite((Test2('testTwo'),))
fifth = unittest.TestSuite((Test3('testOne'),))
sixth = unittest.TestSuite((Test3('testTwo'),))
suite = unittest.TestSuite((first, second, third, fourth, fifth, sixth))
runner = self.getRunner()
result = runner.run(suite)
self.assertEqual(result.testsRun, 6)
self.assertEqual(len(result.errors), 0)
self.assertEqual(results,
['Module1.setUpModule', 'setup 1',
'Test1.testOne', 'Test1.testTwo', 'teardown 1',
'setup 2', 'Test2.testOne', 'Test2.testTwo',
'teardown 2', 'Module1.tearDownModule',
'Module2.setUpModule', 'setup 3',
'Test3.testOne', 'Test3.testTwo',
'teardown 3', 'Module2.tearDownModule'])
def test_setup_module(self):
class Module(object):
moduleSetup = 0
@staticmethod
def setUpModule():
Module.moduleSetup += 1
class Test(unittest.TestCase):
def test_one(self):
pass
def test_two(self):
pass
Test.__module__ = 'Module'
sys.modules['Module'] = Module
result = self.runTests(Test)
self.assertEqual(Module.moduleSetup, 1)
self.assertEqual(result.testsRun, 2)
self.assertEqual(len(result.errors), 0)
def test_error_in_setup_module(self):
class Module(object):
moduleSetup = 0
moduleTornDown = 0
@staticmethod
def setUpModule():
Module.moduleSetup += 1
raise TypeError('foo')
@staticmethod
def tearDownModule():
Module.moduleTornDown += 1
class Test(unittest.TestCase):
classSetUp = False
classTornDown = False
@classmethod
def setUpClass(cls):
Test.classSetUp = True
@classmethod
def tearDownClass(cls):
Test.classTornDown = True
def test_one(self):
pass
def test_two(self):
pass
class Test2(unittest.TestCase):
def test_one(self):
pass
def test_two(self):
pass
Test.__module__ = 'Module'
Test2.__module__ = 'Module'
sys.modules['Module'] = Module
result = self.runTests(Test, Test2)
self.assertEqual(Module.moduleSetup, 1)
self.assertEqual(Module.moduleTornDown, 0)
self.assertEqual(result.testsRun, 0)
self.assertFalse(Test.classSetUp)
self.assertFalse(Test.classTornDown)
self.assertEqual(len(result.errors), 1)
error, _ = result.errors[0]
self.assertEqual(str(error), 'setUpModule (Module)')
def test_testcase_with_missing_module(self):
class Test(unittest.TestCase):
def test_one(self):
pass
def test_two(self):
pass
Test.__module__ = 'Module'
sys.modules.pop('Module', None)
result = self.runTests(Test)
self.assertEqual(result.testsRun, 2)
def test_teardown_module(self):
class Module(object):
moduleTornDown = 0
@staticmethod
def tearDownModule():
Module.moduleTornDown += 1
class Test(unittest.TestCase):
def test_one(self):
pass
def test_two(self):
pass
Test.__module__ = 'Module'
sys.modules['Module'] = Module
result = self.runTests(Test)
self.assertEqual(Module.moduleTornDown, 1)
self.assertEqual(result.testsRun, 2)
self.assertEqual(len(result.errors), 0)
def test_error_in_teardown_module(self):
class Module(object):
moduleTornDown = 0
@staticmethod
def tearDownModule():
Module.moduleTornDown += 1
raise TypeError('foo')
class Test(unittest.TestCase):
classSetUp = False
classTornDown = False
@classmethod
def setUpClass(cls):
Test.classSetUp = True
@classmethod
def tearDownClass(cls):
Test.classTornDown = True
def test_one(self):
pass
def test_two(self):
pass
class Test2(unittest.TestCase):
def test_one(self):
pass
def test_two(self):
pass
Test.__module__ = 'Module'
Test2.__module__ = 'Module'
sys.modules['Module'] = Module
result = self.runTests(Test, Test2)
self.assertEqual(Module.moduleTornDown, 1)
self.assertEqual(result.testsRun, 4)
self.assertTrue(Test.classSetUp)
self.assertTrue(Test.classTornDown)
self.assertEqual(len(result.errors), 1)
error, _ = result.errors[0]
self.assertEqual(str(error), 'tearDownModule (Module)')
def test_skiptest_in_setupclass(self):
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
raise unittest.SkipTest('foo')
def test_one(self):
pass
def test_two(self):
pass
result = self.runTests(Test)
self.assertEqual(result.testsRun, 0)
self.assertEqual(len(result.errors), 0)
self.assertEqual(len(result.skipped), 1)
skipped = result.skipped[0][0]
self.assertEqual(str(skipped),
'setUpClass (%s.%s)' % (__name__, Test.__qualname__))
def test_skiptest_in_setupmodule(self):
class Test(unittest.TestCase):
def test_one(self):
pass
def test_two(self):
pass
class Module(object):
@staticmethod
def setUpModule():
raise unittest.SkipTest('foo')
Test.__module__ = 'Module'
sys.modules['Module'] = Module
result = self.runTests(Test)
self.assertEqual(result.testsRun, 0)
self.assertEqual(len(result.errors), 0)
self.assertEqual(len(result.skipped), 1)
skipped = result.skipped[0][0]
self.assertEqual(str(skipped), 'setUpModule (Module)')
def test_suite_debug_executes_setups_and_teardowns(self):
ordering = []
class Module(object):
@staticmethod
def setUpModule():
ordering.append('setUpModule')
@staticmethod
def tearDownModule():
ordering.append('tearDownModule')
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
ordering.append('setUpClass')
@classmethod
def tearDownClass(cls):
ordering.append('tearDownClass')
def test_something(self):
ordering.append('test_something')
Test.__module__ = 'Module'
sys.modules['Module'] = Module
suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
suite.debug()
expectedOrder = ['setUpModule', 'setUpClass', 'test_something', 'tearDownClass', 'tearDownModule']
self.assertEqual(ordering, expectedOrder)
def test_suite_debug_propagates_exceptions(self):
class Module(object):
@staticmethod
def setUpModule():
if phase == 0:
raise Exception('setUpModule')
@staticmethod
def tearDownModule():
if phase == 1:
raise Exception('tearDownModule')
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
if phase == 2:
raise Exception('setUpClass')
@classmethod
def tearDownClass(cls):
if phase == 3:
raise Exception('tearDownClass')
def test_something(self):
if phase == 4:
raise Exception('test_something')
Test.__module__ = 'Module'
sys.modules['Module'] = Module
messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something')
for phase, msg in enumerate(messages):
_suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
suite = unittest.TestSuite([_suite])
with self.assertRaisesRegex(Exception, msg):
suite.debug()
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,530 @@
import unittest
from test.test_unittest.support import LoggingResult
class Test_TestSkipping(unittest.TestCase):
def test_skipping(self):
class Foo(unittest.TestCase):
def defaultTestResult(self):
return LoggingResult(events)
def test_skip_me(self):
self.skipTest("skip")
events = []
result = LoggingResult(events)
test = Foo("test_skip_me")
self.assertIs(test.run(result), result)
self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
self.assertEqual(result.skipped, [(test, "skip")])
events = []
result = test.run()
self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
'stopTest', 'stopTestRun'])
self.assertEqual(result.skipped, [(test, "skip")])
self.assertEqual(result.testsRun, 1)
# Try letting setUp skip the test now.
class Foo(unittest.TestCase):
def defaultTestResult(self):
return LoggingResult(events)
def setUp(self):
self.skipTest("testing")
def test_nothing(self): pass
events = []
result = LoggingResult(events)
test = Foo("test_nothing")
self.assertIs(test.run(result), result)
self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
self.assertEqual(result.skipped, [(test, "testing")])
self.assertEqual(result.testsRun, 1)
events = []
result = test.run()
self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
'stopTest', 'stopTestRun'])
self.assertEqual(result.skipped, [(test, "testing")])
self.assertEqual(result.testsRun, 1)
def test_skipping_subtests(self):
class Foo(unittest.TestCase):
def defaultTestResult(self):
return LoggingResult(events)
def test_skip_me(self):
with self.subTest(a=1):
with self.subTest(b=2):
self.skipTest("skip 1")
self.skipTest("skip 2")
self.skipTest("skip 3")
events = []
result = LoggingResult(events)
test = Foo("test_skip_me")
self.assertIs(test.run(result), result)
self.assertEqual(events, ['startTest', 'addSkip', 'addSkip',
'addSkip', 'stopTest'])
self.assertEqual(len(result.skipped), 3)
subtest, msg = result.skipped[0]
self.assertEqual(msg, "skip 1")
self.assertIsInstance(subtest, unittest.TestCase)
self.assertIsNot(subtest, test)
subtest, msg = result.skipped[1]
self.assertEqual(msg, "skip 2")
self.assertIsInstance(subtest, unittest.TestCase)
self.assertIsNot(subtest, test)
self.assertEqual(result.skipped[2], (test, "skip 3"))
events = []
result = test.run()
self.assertEqual(events,
['startTestRun', 'startTest', 'addSkip', 'addSkip',
'addSkip', 'stopTest', 'stopTestRun'])
self.assertEqual([msg for subtest, msg in result.skipped],
['skip 1', 'skip 2', 'skip 3'])
def test_skipping_decorators(self):
op_table = ((unittest.skipUnless, False, True),
(unittest.skipIf, True, False))
for deco, do_skip, dont_skip in op_table:
class Foo(unittest.TestCase):
def defaultTestResult(self):
return LoggingResult(events)
@deco(do_skip, "testing")
def test_skip(self): pass
@deco(dont_skip, "testing")
def test_dont_skip(self): pass
test_do_skip = Foo("test_skip")
test_dont_skip = Foo("test_dont_skip")
suite = unittest.TestSuite([test_do_skip, test_dont_skip])
events = []
result = LoggingResult(events)
self.assertIs(suite.run(result), result)
self.assertEqual(len(result.skipped), 1)
expected = ['startTest', 'addSkip', 'stopTest',
'startTest', 'addSuccess', 'stopTest']
self.assertEqual(events, expected)
self.assertEqual(result.testsRun, 2)
self.assertEqual(result.skipped, [(test_do_skip, "testing")])
self.assertTrue(result.wasSuccessful())
events = []
result = test_do_skip.run()
self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
'stopTest', 'stopTestRun'])
self.assertEqual(result.skipped, [(test_do_skip, "testing")])
events = []
result = test_dont_skip.run()
self.assertEqual(events, ['startTestRun', 'startTest', 'addSuccess',
'stopTest', 'stopTestRun'])
self.assertEqual(result.skipped, [])
def test_skip_class(self):
@unittest.skip("testing")
class Foo(unittest.TestCase):
def defaultTestResult(self):
return LoggingResult(events)
def test_1(self):
record.append(1)
events = []
record = []
result = LoggingResult(events)
test = Foo("test_1")
suite = unittest.TestSuite([test])
self.assertIs(suite.run(result), result)
self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
self.assertEqual(result.skipped, [(test, "testing")])
self.assertEqual(record, [])
events = []
result = test.run()
self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
'stopTest', 'stopTestRun'])
self.assertEqual(result.skipped, [(test, "testing")])
self.assertEqual(record, [])
def test_skip_non_unittest_class(self):
@unittest.skip("testing")
class Mixin:
def test_1(self):
record.append(1)
class Foo(Mixin, unittest.TestCase):
pass
record = []
result = unittest.TestResult()
test = Foo("test_1")
suite = unittest.TestSuite([test])
self.assertIs(suite.run(result), result)
self.assertEqual(result.skipped, [(test, "testing")])
self.assertEqual(record, [])
def test_skip_in_setup(self):
class Foo(unittest.TestCase):
def setUp(self):
self.skipTest("skip")
def test_skip_me(self):
self.fail("shouldn't come here")
events = []
result = LoggingResult(events)
test = Foo("test_skip_me")
self.assertIs(test.run(result), result)
self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
self.assertEqual(result.skipped, [(test, "skip")])
def test_skip_in_cleanup(self):
class Foo(unittest.TestCase):
def test_skip_me(self):
pass
def tearDown(self):
self.skipTest("skip")
events = []
result = LoggingResult(events)
test = Foo("test_skip_me")
self.assertIs(test.run(result), result)
self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
self.assertEqual(result.skipped, [(test, "skip")])
def test_failure_and_skip_in_cleanup(self):
class Foo(unittest.TestCase):
def test_skip_me(self):
self.fail("fail")
def tearDown(self):
self.skipTest("skip")
events = []
result = LoggingResult(events)
test = Foo("test_skip_me")
self.assertIs(test.run(result), result)
self.assertEqual(events, ['startTest', 'addFailure', 'addSkip', 'stopTest'])
self.assertEqual(result.skipped, [(test, "skip")])
def test_skipping_and_fail_in_cleanup(self):
class Foo(unittest.TestCase):
def test_skip_me(self):
self.skipTest("skip")
def tearDown(self):
self.fail("fail")
events = []
result = LoggingResult(events)
test = Foo("test_skip_me")
self.assertIs(test.run(result), result)
self.assertEqual(events, ['startTest', 'addSkip', 'addFailure', 'stopTest'])
self.assertEqual(result.skipped, [(test, "skip")])
def test_expected_failure(self):
class Foo(unittest.TestCase):
@unittest.expectedFailure
def test_die(self):
self.fail("help me!")
events = []
result = LoggingResult(events)
test = Foo("test_die")
self.assertIs(test.run(result), result)
self.assertEqual(events,
['startTest', 'addExpectedFailure', 'stopTest'])
self.assertFalse(result.failures)
self.assertEqual(result.expectedFailures[0][0], test)
self.assertFalse(result.unexpectedSuccesses)
self.assertTrue(result.wasSuccessful())
def test_expected_failure_with_wrapped_class(self):
@unittest.expectedFailure
class Foo(unittest.TestCase):
def test_1(self):
self.assertTrue(False)
events = []
result = LoggingResult(events)
test = Foo("test_1")
self.assertIs(test.run(result), result)
self.assertEqual(events,
['startTest', 'addExpectedFailure', 'stopTest'])
self.assertFalse(result.failures)
self.assertEqual(result.expectedFailures[0][0], test)
self.assertFalse(result.unexpectedSuccesses)
self.assertTrue(result.wasSuccessful())
def test_expected_failure_with_wrapped_subclass(self):
class Foo(unittest.TestCase):
def test_1(self):
self.assertTrue(False)
@unittest.expectedFailure
class Bar(Foo):
pass
events = []
result = LoggingResult(events)
test = Bar("test_1")
self.assertIs(test.run(result), result)
self.assertEqual(events,
['startTest', 'addExpectedFailure', 'stopTest'])
self.assertFalse(result.failures)
self.assertEqual(result.expectedFailures[0][0], test)
self.assertFalse(result.unexpectedSuccesses)
self.assertTrue(result.wasSuccessful())
def test_expected_failure_subtests(self):
# A failure in any subtest counts as the expected failure of the
# whole test.
class Foo(unittest.TestCase):
@unittest.expectedFailure
def test_die(self):
with self.subTest():
# This one succeeds
pass
with self.subTest():
self.fail("help me!")
with self.subTest():
# This one doesn't get executed
self.fail("shouldn't come here")
events = []
result = LoggingResult(events)
test = Foo("test_die")
self.assertIs(test.run(result), result)
self.assertEqual(events,
['startTest', 'addSubTestSuccess',
'addExpectedFailure', 'stopTest'])
self.assertFalse(result.failures)
self.assertEqual(len(result.expectedFailures), 1)
self.assertIs(result.expectedFailures[0][0], test)
self.assertFalse(result.unexpectedSuccesses)
self.assertTrue(result.wasSuccessful())
def test_expected_failure_and_fail_in_cleanup(self):
class Foo(unittest.TestCase):
@unittest.expectedFailure
def test_die(self):
self.fail("help me!")
def tearDown(self):
self.fail("bad tearDown")
events = []
result = LoggingResult(events)
test = Foo("test_die")
self.assertIs(test.run(result), result)
self.assertEqual(events,
['startTest', 'addFailure', 'stopTest'])
self.assertEqual(len(result.failures), 1)
self.assertIn('AssertionError: bad tearDown', result.failures[0][1])
self.assertFalse(result.expectedFailures)
self.assertFalse(result.unexpectedSuccesses)
self.assertFalse(result.wasSuccessful())
def test_expected_failure_and_skip_in_cleanup(self):
class Foo(unittest.TestCase):
@unittest.expectedFailure
def test_die(self):
self.fail("help me!")
def tearDown(self):
self.skipTest("skip")
events = []
result = LoggingResult(events)
test = Foo("test_die")
self.assertIs(test.run(result), result)
self.assertEqual(events,
['startTest', 'addSkip', 'stopTest'])
self.assertFalse(result.failures)
self.assertFalse(result.expectedFailures)
self.assertFalse(result.unexpectedSuccesses)
self.assertEqual(result.skipped, [(test, "skip")])
self.assertTrue(result.wasSuccessful())
def test_unexpected_success(self):
class Foo(unittest.TestCase):
@unittest.expectedFailure
def test_die(self):
pass
events = []
result = LoggingResult(events)
test = Foo("test_die")
self.assertIs(test.run(result), result)
self.assertEqual(events,
['startTest', 'addUnexpectedSuccess', 'stopTest'])
self.assertFalse(result.failures)
self.assertFalse(result.expectedFailures)
self.assertEqual(result.unexpectedSuccesses, [test])
self.assertFalse(result.wasSuccessful())
def test_unexpected_success_subtests(self):
# Success in all subtests counts as the unexpected success of
# the whole test.
class Foo(unittest.TestCase):
@unittest.expectedFailure
def test_die(self):
with self.subTest():
# This one succeeds
pass
with self.subTest():
# So does this one
pass
events = []
result = LoggingResult(events)
test = Foo("test_die")
self.assertIs(test.run(result), result)
self.assertEqual(events,
['startTest',
'addSubTestSuccess', 'addSubTestSuccess',
'addUnexpectedSuccess', 'stopTest'])
self.assertFalse(result.failures)
self.assertFalse(result.expectedFailures)
self.assertEqual(result.unexpectedSuccesses, [test])
self.assertFalse(result.wasSuccessful())
def test_unexpected_success_and_fail_in_cleanup(self):
class Foo(unittest.TestCase):
@unittest.expectedFailure
def test_die(self):
pass
def tearDown(self):
self.fail("bad tearDown")
events = []
result = LoggingResult(events)
test = Foo("test_die")
self.assertIs(test.run(result), result)
self.assertEqual(events,
['startTest', 'addFailure', 'stopTest'])
self.assertEqual(len(result.failures), 1)
self.assertIn('AssertionError: bad tearDown', result.failures[0][1])
self.assertFalse(result.expectedFailures)
self.assertFalse(result.unexpectedSuccesses)
self.assertFalse(result.wasSuccessful())
def test_unexpected_success_and_skip_in_cleanup(self):
class Foo(unittest.TestCase):
@unittest.expectedFailure
def test_die(self):
pass
def tearDown(self):
self.skipTest("skip")
events = []
result = LoggingResult(events)
test = Foo("test_die")
self.assertIs(test.run(result), result)
self.assertEqual(events,
['startTest', 'addSkip', 'stopTest'])
self.assertFalse(result.failures)
self.assertFalse(result.expectedFailures)
self.assertFalse(result.unexpectedSuccesses)
self.assertEqual(result.skipped, [(test, "skip")])
self.assertTrue(result.wasSuccessful())
def test_skip_doesnt_run_setup(self):
class Foo(unittest.TestCase):
wasSetUp = False
wasTornDown = False
def setUp(self):
Foo.wasSetUp = True
def tornDown(self):
Foo.wasTornDown = True
@unittest.skip('testing')
def test_1(self):
pass
result = unittest.TestResult()
test = Foo("test_1")
suite = unittest.TestSuite([test])
self.assertIs(suite.run(result), result)
self.assertEqual(result.skipped, [(test, "testing")])
self.assertFalse(Foo.wasSetUp)
self.assertFalse(Foo.wasTornDown)
def test_decorated_skip(self):
def decorator(func):
def inner(*a):
return func(*a)
return inner
class Foo(unittest.TestCase):
@decorator
@unittest.skip('testing')
def test_1(self):
pass
result = unittest.TestResult()
test = Foo("test_1")
suite = unittest.TestSuite([test])
self.assertIs(suite.run(result), result)
self.assertEqual(result.skipped, [(test, "testing")])
def test_skip_without_reason(self):
class Foo(unittest.TestCase):
@unittest.skip
def test_1(self):
pass
result = unittest.TestResult()
test = Foo("test_1")
suite = unittest.TestSuite([test])
self.assertIs(suite.run(result), result)
self.assertEqual(result.skipped, [(test, "")])
def test_debug_skipping(self):
class Foo(unittest.TestCase):
def setUp(self):
events.append("setUp")
def tearDown(self):
events.append("tearDown")
def test1(self):
self.skipTest('skipping exception')
events.append("test1")
@unittest.skip("skipping decorator")
def test2(self):
events.append("test2")
events = []
test = Foo("test1")
with self.assertRaises(unittest.SkipTest) as cm:
test.debug()
self.assertIn("skipping exception", str(cm.exception))
self.assertEqual(events, ["setUp"])
events = []
test = Foo("test2")
with self.assertRaises(unittest.SkipTest) as cm:
test.debug()
self.assertIn("skipping decorator", str(cm.exception))
self.assertEqual(events, [])
def test_debug_skipping_class(self):
@unittest.skip("testing")
class Foo(unittest.TestCase):
def setUp(self):
events.append("setUp")
def tearDown(self):
events.append("tearDown")
def test(self):
events.append("test")
events = []
test = Foo("test")
with self.assertRaises(unittest.SkipTest) as cm:
test.debug()
self.assertIn("testing", str(cm.exception))
self.assertEqual(events, [])
def test_debug_skipping_subtests(self):
class Foo(unittest.TestCase):
def setUp(self):
events.append("setUp")
def tearDown(self):
events.append("tearDown")
def test(self):
with self.subTest(a=1):
events.append('subtest')
self.skipTest("skip subtest")
events.append('end subtest')
events.append('end test')
events = []
result = LoggingResult(events)
test = Foo("test")
with self.assertRaises(unittest.SkipTest) as cm:
test.debug()
self.assertIn("skip subtest", str(cm.exception))
self.assertEqual(events, ['setUp', 'subtest'])
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,447 @@
import unittest
import gc
import sys
import weakref
from test.test_unittest.support import LoggingResult, TestEquality
### Support code for Test_TestSuite
################################################################
class Test(object):
class Foo(unittest.TestCase):
def test_1(self): pass
def test_2(self): pass
def test_3(self): pass
def runTest(self): pass
def _mk_TestSuite(*names):
return unittest.TestSuite(Test.Foo(n) for n in names)
################################################################
class Test_TestSuite(unittest.TestCase, TestEquality):
### Set up attributes needed by inherited tests
################################################################
# Used by TestEquality.test_eq
eq_pairs = [(unittest.TestSuite(), unittest.TestSuite())
,(unittest.TestSuite(), unittest.TestSuite([]))
,(_mk_TestSuite('test_1'), _mk_TestSuite('test_1'))]
# Used by TestEquality.test_ne
ne_pairs = [(unittest.TestSuite(), _mk_TestSuite('test_1'))
,(unittest.TestSuite([]), _mk_TestSuite('test_1'))
,(_mk_TestSuite('test_1', 'test_2'), _mk_TestSuite('test_1', 'test_3'))
,(_mk_TestSuite('test_1'), _mk_TestSuite('test_2'))]
################################################################
### /Set up attributes needed by inherited tests
### Tests for TestSuite.__init__
################################################################
# "class TestSuite([tests])"
#
# The tests iterable should be optional
def test_init__tests_optional(self):
suite = unittest.TestSuite()
self.assertEqual(suite.countTestCases(), 0)
# countTestCases() still works after tests are run
suite.run(unittest.TestResult())
self.assertEqual(suite.countTestCases(), 0)
# "class TestSuite([tests])"
# ...
# "If tests is given, it must be an iterable of individual test cases
# or other test suites that will be used to build the suite initially"
#
# TestSuite should deal with empty tests iterables by allowing the
# creation of an empty suite
def test_init__empty_tests(self):
suite = unittest.TestSuite([])
self.assertEqual(suite.countTestCases(), 0)
# countTestCases() still works after tests are run
suite.run(unittest.TestResult())
self.assertEqual(suite.countTestCases(), 0)
# "class TestSuite([tests])"
# ...
# "If tests is given, it must be an iterable of individual test cases
# or other test suites that will be used to build the suite initially"
#
# TestSuite should allow any iterable to provide tests
def test_init__tests_from_any_iterable(self):
def tests():
yield unittest.FunctionTestCase(lambda: None)
yield unittest.FunctionTestCase(lambda: None)
suite_1 = unittest.TestSuite(tests())
self.assertEqual(suite_1.countTestCases(), 2)
suite_2 = unittest.TestSuite(suite_1)
self.assertEqual(suite_2.countTestCases(), 2)
suite_3 = unittest.TestSuite(set(suite_1))
self.assertEqual(suite_3.countTestCases(), 2)
# countTestCases() still works after tests are run
suite_1.run(unittest.TestResult())
self.assertEqual(suite_1.countTestCases(), 2)
suite_2.run(unittest.TestResult())
self.assertEqual(suite_2.countTestCases(), 2)
suite_3.run(unittest.TestResult())
self.assertEqual(suite_3.countTestCases(), 2)
# "class TestSuite([tests])"
# ...
# "If tests is given, it must be an iterable of individual test cases
# or other test suites that will be used to build the suite initially"
#
# Does TestSuite() also allow other TestSuite() instances to be present
# in the tests iterable?
def test_init__TestSuite_instances_in_tests(self):
def tests():
ftc = unittest.FunctionTestCase(lambda: None)
yield unittest.TestSuite([ftc])
yield unittest.FunctionTestCase(lambda: None)
suite = unittest.TestSuite(tests())
self.assertEqual(suite.countTestCases(), 2)
# countTestCases() still works after tests are run
suite.run(unittest.TestResult())
self.assertEqual(suite.countTestCases(), 2)
################################################################
### /Tests for TestSuite.__init__
# Container types should support the iter protocol
def test_iter(self):
test1 = unittest.FunctionTestCase(lambda: None)
test2 = unittest.FunctionTestCase(lambda: None)
suite = unittest.TestSuite((test1, test2))
self.assertEqual(list(suite), [test1, test2])
# "Return the number of tests represented by the this test object.
# ...this method is also implemented by the TestSuite class, which can
# return larger [greater than 1] values"
#
# Presumably an empty TestSuite returns 0?
def test_countTestCases_zero_simple(self):
suite = unittest.TestSuite()
self.assertEqual(suite.countTestCases(), 0)
# "Return the number of tests represented by the this test object.
# ...this method is also implemented by the TestSuite class, which can
# return larger [greater than 1] values"
#
# Presumably an empty TestSuite (even if it contains other empty
# TestSuite instances) returns 0?
def test_countTestCases_zero_nested(self):
class Test1(unittest.TestCase):
def test(self):
pass
suite = unittest.TestSuite([unittest.TestSuite()])
self.assertEqual(suite.countTestCases(), 0)
# "Return the number of tests represented by the this test object.
# ...this method is also implemented by the TestSuite class, which can
# return larger [greater than 1] values"
def test_countTestCases_simple(self):
test1 = unittest.FunctionTestCase(lambda: None)
test2 = unittest.FunctionTestCase(lambda: None)
suite = unittest.TestSuite((test1, test2))
self.assertEqual(suite.countTestCases(), 2)
# countTestCases() still works after tests are run
suite.run(unittest.TestResult())
self.assertEqual(suite.countTestCases(), 2)
# "Return the number of tests represented by the this test object.
# ...this method is also implemented by the TestSuite class, which can
# return larger [greater than 1] values"
#
# Make sure this holds for nested TestSuite instances, too
def test_countTestCases_nested(self):
class Test1(unittest.TestCase):
def test1(self): pass
def test2(self): pass
test2 = unittest.FunctionTestCase(lambda: None)
test3 = unittest.FunctionTestCase(lambda: None)
child = unittest.TestSuite((Test1('test2'), test2))
parent = unittest.TestSuite((test3, child, Test1('test1')))
self.assertEqual(parent.countTestCases(), 4)
# countTestCases() still works after tests are run
parent.run(unittest.TestResult())
self.assertEqual(parent.countTestCases(), 4)
self.assertEqual(child.countTestCases(), 2)
# "Run the tests associated with this suite, collecting the result into
# the test result object passed as result."
#
# And if there are no tests? What then?
def test_run__empty_suite(self):
events = []
result = LoggingResult(events)
suite = unittest.TestSuite()
suite.run(result)
self.assertEqual(events, [])
# "Note that unlike TestCase.run(), TestSuite.run() requires the
# "result object to be passed in."
def test_run__requires_result(self):
suite = unittest.TestSuite()
try:
suite.run()
except TypeError:
pass
else:
self.fail("Failed to raise TypeError")
# "Run the tests associated with this suite, collecting the result into
# the test result object passed as result."
def test_run(self):
events = []
result = LoggingResult(events)
class LoggingCase(unittest.TestCase):
def run(self, result):
events.append('run %s' % self._testMethodName)
def test1(self): pass
def test2(self): pass
tests = [LoggingCase('test1'), LoggingCase('test2')]
unittest.TestSuite(tests).run(result)
self.assertEqual(events, ['run test1', 'run test2'])
# "Add a TestCase ... to the suite"
def test_addTest__TestCase(self):
class Foo(unittest.TestCase):
def test(self): pass
test = Foo('test')
suite = unittest.TestSuite()
suite.addTest(test)
self.assertEqual(suite.countTestCases(), 1)
self.assertEqual(list(suite), [test])
# countTestCases() still works after tests are run
suite.run(unittest.TestResult())
self.assertEqual(suite.countTestCases(), 1)
# "Add a ... TestSuite to the suite"
def test_addTest__TestSuite(self):
class Foo(unittest.TestCase):
def test(self): pass
suite_2 = unittest.TestSuite([Foo('test')])
suite = unittest.TestSuite()
suite.addTest(suite_2)
self.assertEqual(suite.countTestCases(), 1)
self.assertEqual(list(suite), [suite_2])
# countTestCases() still works after tests are run
suite.run(unittest.TestResult())
self.assertEqual(suite.countTestCases(), 1)
# "Add all the tests from an iterable of TestCase and TestSuite
# instances to this test suite."
#
# "This is equivalent to iterating over tests, calling addTest() for
# each element"
def test_addTests(self):
class Foo(unittest.TestCase):
def test_1(self): pass
def test_2(self): pass
test_1 = Foo('test_1')
test_2 = Foo('test_2')
inner_suite = unittest.TestSuite([test_2])
def gen():
yield test_1
yield test_2
yield inner_suite
suite_1 = unittest.TestSuite()
suite_1.addTests(gen())
self.assertEqual(list(suite_1), list(gen()))
# "This is equivalent to iterating over tests, calling addTest() for
# each element"
suite_2 = unittest.TestSuite()
for t in gen():
suite_2.addTest(t)
self.assertEqual(suite_1, suite_2)
# "Add all the tests from an iterable of TestCase and TestSuite
# instances to this test suite."
#
# What happens if it doesn't get an iterable?
def test_addTest__noniterable(self):
suite = unittest.TestSuite()
try:
suite.addTests(5)
except TypeError:
pass
else:
self.fail("Failed to raise TypeError")
def test_addTest__noncallable(self):
suite = unittest.TestSuite()
self.assertRaises(TypeError, suite.addTest, 5)
def test_addTest__casesuiteclass(self):
suite = unittest.TestSuite()
self.assertRaises(TypeError, suite.addTest, Test_TestSuite)
self.assertRaises(TypeError, suite.addTest, unittest.TestSuite)
def test_addTests__string(self):
suite = unittest.TestSuite()
self.assertRaises(TypeError, suite.addTests, "foo")
def test_function_in_suite(self):
def f(_):
pass
suite = unittest.TestSuite()
suite.addTest(f)
# when the bug is fixed this line will not crash
suite.run(unittest.TestResult())
def test_remove_test_at_index(self):
if not unittest.BaseTestSuite._cleanup:
raise unittest.SkipTest("Suite cleanup is disabled")
suite = unittest.TestSuite()
suite._tests = [1, 2, 3]
suite._removeTestAtIndex(1)
self.assertEqual([1, None, 3], suite._tests)
def test_remove_test_at_index_not_indexable(self):
if not unittest.BaseTestSuite._cleanup:
raise unittest.SkipTest("Suite cleanup is disabled")
suite = unittest.TestSuite()
suite._tests = None
# if _removeAtIndex raises for noniterables this next line will break
suite._removeTestAtIndex(2)
def assert_garbage_collect_test_after_run(self, TestSuiteClass):
if not unittest.BaseTestSuite._cleanup:
raise unittest.SkipTest("Suite cleanup is disabled")
class Foo(unittest.TestCase):
def test_nothing(self):
pass
test = Foo('test_nothing')
wref = weakref.ref(test)
suite = TestSuiteClass([wref()])
suite.run(unittest.TestResult())
del test
# for the benefit of non-reference counting implementations
gc.collect()
self.assertEqual(suite._tests, [None])
self.assertIsNone(wref())
def test_garbage_collect_test_after_run_BaseTestSuite(self):
self.assert_garbage_collect_test_after_run(unittest.BaseTestSuite)
def test_garbage_collect_test_after_run_TestSuite(self):
self.assert_garbage_collect_test_after_run(unittest.TestSuite)
def test_basetestsuite(self):
class Test(unittest.TestCase):
wasSetUp = False
wasTornDown = False
@classmethod
def setUpClass(cls):
cls.wasSetUp = True
@classmethod
def tearDownClass(cls):
cls.wasTornDown = True
def testPass(self):
pass
def testFail(self):
fail
class Module(object):
wasSetUp = False
wasTornDown = False
@staticmethod
def setUpModule():
Module.wasSetUp = True
@staticmethod
def tearDownModule():
Module.wasTornDown = True
Test.__module__ = 'Module'
sys.modules['Module'] = Module
self.addCleanup(sys.modules.pop, 'Module')
suite = unittest.BaseTestSuite()
suite.addTests([Test('testPass'), Test('testFail')])
self.assertEqual(suite.countTestCases(), 2)
result = unittest.TestResult()
suite.run(result)
self.assertFalse(Module.wasSetUp)
self.assertFalse(Module.wasTornDown)
self.assertFalse(Test.wasSetUp)
self.assertFalse(Test.wasTornDown)
self.assertEqual(len(result.errors), 1)
self.assertEqual(len(result.failures), 0)
self.assertEqual(result.testsRun, 2)
self.assertEqual(suite.countTestCases(), 2)
def test_overriding_call(self):
class MySuite(unittest.TestSuite):
called = False
def __call__(self, *args, **kw):
self.called = True
unittest.TestSuite.__call__(self, *args, **kw)
suite = MySuite()
result = unittest.TestResult()
wrapper = unittest.TestSuite()
wrapper.addTest(suite)
wrapper(result)
self.assertTrue(suite.called)
# reusing results should be permitted even if abominable
self.assertFalse(result._testRunEntered)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,33 @@
import unittest
from unittest.util import safe_repr, sorted_list_difference, unorderable_list_difference
class TestUtil(unittest.TestCase):
def test_safe_repr(self):
class RaisingRepr:
def __repr__(self):
raise ValueError("Invalid repr()")
class LongRepr:
def __repr__(self):
return 'x' * 100
safe_repr(RaisingRepr())
self.assertEqual(safe_repr('foo'), "'foo'")
self.assertEqual(safe_repr(LongRepr(), short=True), 'x'*80 + ' [truncated]...')
def test_sorted_list_difference(self):
self.assertEqual(sorted_list_difference([], []), ([], []))
self.assertEqual(sorted_list_difference([1, 2], [2, 3]), ([1], [3]))
self.assertEqual(sorted_list_difference([1, 2], [1, 3]), ([2], [3]))
self.assertEqual(sorted_list_difference([1, 1, 1], [1, 2, 3]), ([], [2, 3]))
self.assertEqual(sorted_list_difference([4], [1, 2, 3, 4]), ([], [1, 2, 3]))
self.assertEqual(sorted_list_difference([1, 1], [2]), ([1], [2]))
self.assertEqual(sorted_list_difference([2], [1, 1]), ([2], [1]))
self.assertEqual(sorted_list_difference([1, 2], [1, 1]), ([2], []))
def test_unorderable_list_difference(self):
self.assertEqual(unorderable_list_difference([], []), ([], []))
self.assertEqual(unorderable_list_difference([1, 2], []), ([2, 1], []))
self.assertEqual(unorderable_list_difference([], [1, 2]), ([], [1, 2]))
self.assertEqual(unorderable_list_difference([1, 2], [1, 3]), ([2], [3]))

View File

@ -0,0 +1,6 @@
import os.path
from test.support import load_package_tests
def load_tests(*args):
return load_package_tests(os.path.dirname(__file__), *args)

View File

@ -0,0 +1,18 @@
import os
import unittest
def load_tests(loader, standard_tests, pattern):
# top level directory cached on loader instance
this_dir = os.path.dirname(__file__)
pattern = pattern or "test*.py"
# We are inside test.test_unittest.testmock, so the top-level is three notches up
top_level_dir = os.path.dirname(os.path.dirname(os.path.dirname(this_dir)))
package_tests = loader.discover(start_dir=this_dir, pattern=pattern,
top_level_dir=top_level_dir)
standard_tests.addTests(package_tests)
return standard_tests
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,27 @@
target = {'foo': 'FOO'}
def is_instance(obj, klass):
"""Version of is_instance that doesn't access __class__"""
return issubclass(type(obj), klass)
class SomeClass(object):
class_attribute = None
def wibble(self): pass
class X(object):
pass
# A standin for weurkzeug.local.LocalProxy - issue 119600
def _inaccessible(*args, **kwargs):
raise AttributeError
class OpaqueProxy:
__getattribute__ = _inaccessible
g = OpaqueProxy()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,150 @@
# Copyright (C) 2007-2012 Michael Foord & the mock team
# E-mail: fuzzyman AT voidspace DOT org DOT uk
# http://www.voidspace.org.uk/python/mock/
import unittest
from test.test_unittest.testmock.support import is_instance, X, SomeClass
from unittest.mock import (
Mock, MagicMock, NonCallableMagicMock,
NonCallableMock, patch, create_autospec,
CallableMixin
)
class TestCallable(unittest.TestCase):
def assertNotCallable(self, mock):
self.assertTrue(is_instance(mock, NonCallableMagicMock))
self.assertFalse(is_instance(mock, CallableMixin))
def test_non_callable(self):
for mock in NonCallableMagicMock(), NonCallableMock():
self.assertRaises(TypeError, mock)
self.assertFalse(hasattr(mock, '__call__'))
self.assertIn(mock.__class__.__name__, repr(mock))
def test_hierarchy(self):
self.assertTrue(issubclass(MagicMock, Mock))
self.assertTrue(issubclass(NonCallableMagicMock, NonCallableMock))
def test_attributes(self):
one = NonCallableMock()
self.assertTrue(issubclass(type(one.one), Mock))
two = NonCallableMagicMock()
self.assertTrue(issubclass(type(two.two), MagicMock))
def test_subclasses(self):
class MockSub(Mock):
pass
one = MockSub()
self.assertTrue(issubclass(type(one.one), MockSub))
class MagicSub(MagicMock):
pass
two = MagicSub()
self.assertTrue(issubclass(type(two.two), MagicSub))
def test_patch_spec(self):
patcher = patch('%s.X' % __name__, spec=True)
mock = patcher.start()
self.addCleanup(patcher.stop)
instance = mock()
mock.assert_called_once_with()
self.assertNotCallable(instance)
self.assertRaises(TypeError, instance)
def test_patch_spec_set(self):
patcher = patch('%s.X' % __name__, spec_set=True)
mock = patcher.start()
self.addCleanup(patcher.stop)
instance = mock()
mock.assert_called_once_with()
self.assertNotCallable(instance)
self.assertRaises(TypeError, instance)
def test_patch_spec_instance(self):
patcher = patch('%s.X' % __name__, spec=X())
mock = patcher.start()
self.addCleanup(patcher.stop)
self.assertNotCallable(mock)
self.assertRaises(TypeError, mock)
def test_patch_spec_set_instance(self):
patcher = patch('%s.X' % __name__, spec_set=X())
mock = patcher.start()
self.addCleanup(patcher.stop)
self.assertNotCallable(mock)
self.assertRaises(TypeError, mock)
def test_patch_spec_callable_class(self):
class CallableX(X):
def __call__(self): pass
class Sub(CallableX):
pass
class Multi(SomeClass, Sub):
pass
for arg in 'spec', 'spec_set':
for Klass in CallableX, Sub, Multi:
with patch('%s.X' % __name__, **{arg: Klass}) as mock:
instance = mock()
mock.assert_called_once_with()
self.assertTrue(is_instance(instance, MagicMock))
# inherited spec
self.assertRaises(AttributeError, getattr, instance,
'foobarbaz')
result = instance()
# instance is callable, result has no spec
instance.assert_called_once_with()
result(3, 2, 1)
result.assert_called_once_with(3, 2, 1)
result.foo(3, 2, 1)
result.foo.assert_called_once_with(3, 2, 1)
def test_create_autospec(self):
mock = create_autospec(X)
instance = mock()
self.assertRaises(TypeError, instance)
mock = create_autospec(X())
self.assertRaises(TypeError, mock)
def test_create_autospec_instance(self):
mock = create_autospec(SomeClass, instance=True)
self.assertRaises(TypeError, mock)
mock.wibble()
mock.wibble.assert_called_once_with()
self.assertRaises(TypeError, mock.wibble, 'some', 'args')
if __name__ == "__main__":
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,548 @@
import math
import unittest
import os
from asyncio import iscoroutinefunction
from unittest.mock import AsyncMock, Mock, MagicMock, _magics
class TestMockingMagicMethods(unittest.TestCase):
def test_deleting_magic_methods(self):
mock = Mock()
self.assertFalse(hasattr(mock, '__getitem__'))
mock.__getitem__ = Mock()
self.assertTrue(hasattr(mock, '__getitem__'))
del mock.__getitem__
self.assertFalse(hasattr(mock, '__getitem__'))
def test_magicmock_del(self):
mock = MagicMock()
# before using getitem
del mock.__getitem__
self.assertRaises(TypeError, lambda: mock['foo'])
mock = MagicMock()
# this time use it first
mock['foo']
del mock.__getitem__
self.assertRaises(TypeError, lambda: mock['foo'])
def test_magic_method_wrapping(self):
mock = Mock()
def f(self, name):
return self, 'fish'
mock.__getitem__ = f
self.assertIsNot(mock.__getitem__, f)
self.assertEqual(mock['foo'], (mock, 'fish'))
self.assertEqual(mock.__getitem__('foo'), (mock, 'fish'))
mock.__getitem__ = mock
self.assertIs(mock.__getitem__, mock)
def test_magic_methods_isolated_between_mocks(self):
mock1 = Mock()
mock2 = Mock()
mock1.__iter__ = Mock(return_value=iter([]))
self.assertEqual(list(mock1), [])
self.assertRaises(TypeError, lambda: list(mock2))
def test_repr(self):
mock = Mock()
self.assertEqual(repr(mock), "<Mock id='%s'>" % id(mock))
mock.__repr__ = lambda s: 'foo'
self.assertEqual(repr(mock), 'foo')
def test_str(self):
mock = Mock()
self.assertEqual(str(mock), object.__str__(mock))
mock.__str__ = lambda s: 'foo'
self.assertEqual(str(mock), 'foo')
def test_dict_methods(self):
mock = Mock()
self.assertRaises(TypeError, lambda: mock['foo'])
def _del():
del mock['foo']
def _set():
mock['foo'] = 3
self.assertRaises(TypeError, _del)
self.assertRaises(TypeError, _set)
_dict = {}
def getitem(s, name):
return _dict[name]
def setitem(s, name, value):
_dict[name] = value
def delitem(s, name):
del _dict[name]
mock.__setitem__ = setitem
mock.__getitem__ = getitem
mock.__delitem__ = delitem
self.assertRaises(KeyError, lambda: mock['foo'])
mock['foo'] = 'bar'
self.assertEqual(_dict, {'foo': 'bar'})
self.assertEqual(mock['foo'], 'bar')
del mock['foo']
self.assertEqual(_dict, {})
def test_numeric(self):
original = mock = Mock()
mock.value = 0
self.assertRaises(TypeError, lambda: mock + 3)
def add(self, other):
mock.value += other
return self
mock.__add__ = add
self.assertEqual(mock + 3, mock)
self.assertEqual(mock.value, 3)
del mock.__add__
def iadd(mock):
mock += 3
self.assertRaises(TypeError, iadd, mock)
mock.__iadd__ = add
mock += 6
self.assertEqual(mock, original)
self.assertEqual(mock.value, 9)
self.assertRaises(TypeError, lambda: 3 + mock)
mock.__radd__ = add
self.assertEqual(7 + mock, mock)
self.assertEqual(mock.value, 16)
def test_division(self):
original = mock = Mock()
mock.value = 32
self.assertRaises(TypeError, lambda: mock / 2)
def truediv(self, other):
mock.value /= other
return self
mock.__truediv__ = truediv
self.assertEqual(mock / 2, mock)
self.assertEqual(mock.value, 16)
del mock.__truediv__
def itruediv(mock):
mock /= 4
self.assertRaises(TypeError, itruediv, mock)
mock.__itruediv__ = truediv
mock /= 8
self.assertEqual(mock, original)
self.assertEqual(mock.value, 2)
self.assertRaises(TypeError, lambda: 8 / mock)
mock.__rtruediv__ = truediv
self.assertEqual(0.5 / mock, mock)
self.assertEqual(mock.value, 4)
def test_hash(self):
mock = Mock()
# test delegation
self.assertEqual(hash(mock), Mock.__hash__(mock))
def _hash(s):
return 3
mock.__hash__ = _hash
self.assertEqual(hash(mock), 3)
def test_nonzero(self):
m = Mock()
self.assertTrue(bool(m))
m.__bool__ = lambda s: False
self.assertFalse(bool(m))
def test_comparison(self):
mock = Mock()
def comp(s, o):
return True
mock.__lt__ = mock.__gt__ = mock.__le__ = mock.__ge__ = comp
self. assertTrue(mock < 3)
self. assertTrue(mock > 3)
self. assertTrue(mock <= 3)
self. assertTrue(mock >= 3)
self.assertRaises(TypeError, lambda: MagicMock() < object())
self.assertRaises(TypeError, lambda: object() < MagicMock())
self.assertRaises(TypeError, lambda: MagicMock() < MagicMock())
self.assertRaises(TypeError, lambda: MagicMock() > object())
self.assertRaises(TypeError, lambda: object() > MagicMock())
self.assertRaises(TypeError, lambda: MagicMock() > MagicMock())
self.assertRaises(TypeError, lambda: MagicMock() <= object())
self.assertRaises(TypeError, lambda: object() <= MagicMock())
self.assertRaises(TypeError, lambda: MagicMock() <= MagicMock())
self.assertRaises(TypeError, lambda: MagicMock() >= object())
self.assertRaises(TypeError, lambda: object() >= MagicMock())
self.assertRaises(TypeError, lambda: MagicMock() >= MagicMock())
def test_equality(self):
for mock in Mock(), MagicMock():
self.assertEqual(mock == mock, True)
self.assertIsInstance(mock == mock, bool)
self.assertEqual(mock != mock, False)
self.assertIsInstance(mock != mock, bool)
self.assertEqual(mock == object(), False)
self.assertEqual(mock != object(), True)
def eq(self, other):
return other == 3
mock.__eq__ = eq
self.assertTrue(mock == 3)
self.assertFalse(mock == 4)
def ne(self, other):
return other == 3
mock.__ne__ = ne
self.assertTrue(mock != 3)
self.assertFalse(mock != 4)
mock = MagicMock()
mock.__eq__.return_value = True
self.assertIsInstance(mock == 3, bool)
self.assertEqual(mock == 3, True)
mock.__ne__.return_value = False
self.assertIsInstance(mock != 3, bool)
self.assertEqual(mock != 3, False)
def test_len_contains_iter(self):
mock = Mock()
self.assertRaises(TypeError, len, mock)
self.assertRaises(TypeError, iter, mock)
self.assertRaises(TypeError, lambda: 'foo' in mock)
mock.__len__ = lambda s: 6
self.assertEqual(len(mock), 6)
mock.__contains__ = lambda s, o: o == 3
self.assertIn(3, mock)
self.assertNotIn(6, mock)
mock.__iter__ = lambda s: iter('foobarbaz')
self.assertEqual(list(mock), list('foobarbaz'))
def test_magicmock(self):
mock = MagicMock()
mock.__iter__.return_value = iter([1, 2, 3])
self.assertEqual(list(mock), [1, 2, 3])
getattr(mock, '__bool__').return_value = False
self.assertFalse(hasattr(mock, '__nonzero__'))
self.assertFalse(bool(mock))
for entry in _magics:
self.assertTrue(hasattr(mock, entry))
self.assertFalse(hasattr(mock, '__imaginary__'))
def test_magic_mock_equality(self):
mock = MagicMock()
self.assertIsInstance(mock == object(), bool)
self.assertIsInstance(mock != object(), bool)
self.assertEqual(mock == object(), False)
self.assertEqual(mock != object(), True)
self.assertEqual(mock == mock, True)
self.assertEqual(mock != mock, False)
def test_asyncmock_defaults(self):
mock = AsyncMock()
self.assertEqual(int(mock), 1)
self.assertEqual(complex(mock), 1j)
self.assertEqual(float(mock), 1.0)
self.assertNotIn(object(), mock)
self.assertEqual(len(mock), 0)
self.assertEqual(list(mock), [])
self.assertEqual(hash(mock), object.__hash__(mock))
self.assertEqual(str(mock), object.__str__(mock))
self.assertTrue(bool(mock))
self.assertEqual(round(mock), mock.__round__())
self.assertEqual(math.trunc(mock), mock.__trunc__())
self.assertEqual(math.floor(mock), mock.__floor__())
self.assertEqual(math.ceil(mock), mock.__ceil__())
self.assertTrue(iscoroutinefunction(mock.__aexit__))
self.assertTrue(iscoroutinefunction(mock.__aenter__))
self.assertIsInstance(mock.__aenter__, AsyncMock)
self.assertIsInstance(mock.__aexit__, AsyncMock)
# in Python 3 oct and hex use __index__
# so these tests are for __index__ in py3k
self.assertEqual(oct(mock), '0o1')
self.assertEqual(hex(mock), '0x1')
# how to test __sizeof__ ?
def test_magicmock_defaults(self):
mock = MagicMock()
self.assertEqual(int(mock), 1)
self.assertEqual(complex(mock), 1j)
self.assertEqual(float(mock), 1.0)
self.assertNotIn(object(), mock)
self.assertEqual(len(mock), 0)
self.assertEqual(list(mock), [])
self.assertEqual(hash(mock), object.__hash__(mock))
self.assertEqual(str(mock), object.__str__(mock))
self.assertTrue(bool(mock))
self.assertEqual(round(mock), mock.__round__())
self.assertEqual(math.trunc(mock), mock.__trunc__())
self.assertEqual(math.floor(mock), mock.__floor__())
self.assertEqual(math.ceil(mock), mock.__ceil__())
self.assertTrue(iscoroutinefunction(mock.__aexit__))
self.assertTrue(iscoroutinefunction(mock.__aenter__))
self.assertIsInstance(mock.__aenter__, AsyncMock)
self.assertIsInstance(mock.__aexit__, AsyncMock)
# in Python 3 oct and hex use __index__
# so these tests are for __index__ in py3k
self.assertEqual(oct(mock), '0o1')
self.assertEqual(hex(mock), '0x1')
# how to test __sizeof__ ?
def test_magic_methods_fspath(self):
mock = MagicMock()
expected_path = mock.__fspath__()
mock.reset_mock()
self.assertEqual(os.fspath(mock), expected_path)
mock.__fspath__.assert_called_once()
def test_magic_mock_does_not_reset_magic_returns(self):
# https://github.com/python/cpython/issues/123934
for reset in (True, False):
with self.subTest(reset=reset):
mm = MagicMock()
self.assertIs(type(mm.__str__()), str)
mm.__str__.assert_called_once()
self.assertIs(type(mm.__hash__()), int)
mm.__hash__.assert_called_once()
for _ in range(3):
# Repeat reset several times to be sure:
mm.reset_mock(return_value=reset)
self.assertIs(type(mm.__str__()), str)
mm.__str__.assert_called_once()
self.assertIs(type(mm.__hash__()), int)
mm.__hash__.assert_called_once()
def test_magic_mock_resets_manual_mocks(self):
mm = MagicMock()
mm.__iter__ = MagicMock(return_value=iter([1]))
mm.custom = MagicMock(return_value=2)
self.assertEqual(list(iter(mm)), [1])
self.assertEqual(mm.custom(), 2)
mm.reset_mock(return_value=True)
self.assertEqual(list(iter(mm)), [])
self.assertIsInstance(mm.custom(), MagicMock)
def test_magic_mock_resets_manual_mocks_empty_iter(self):
mm = MagicMock()
mm.__iter__.return_value = []
self.assertEqual(list(iter(mm)), [])
mm.reset_mock(return_value=True)
self.assertEqual(list(iter(mm)), [])
def test_magic_methods_and_spec(self):
class Iterable(object):
def __iter__(self): pass
mock = Mock(spec=Iterable)
self.assertRaises(AttributeError, lambda: mock.__iter__)
mock.__iter__ = Mock(return_value=iter([]))
self.assertEqual(list(mock), [])
class NonIterable(object):
pass
mock = Mock(spec=NonIterable)
self.assertRaises(AttributeError, lambda: mock.__iter__)
def set_int():
mock.__int__ = Mock(return_value=iter([]))
self.assertRaises(AttributeError, set_int)
mock = MagicMock(spec=Iterable)
self.assertEqual(list(mock), [])
self.assertRaises(AttributeError, set_int)
def test_magic_methods_and_spec_set(self):
class Iterable(object):
def __iter__(self): pass
mock = Mock(spec_set=Iterable)
self.assertRaises(AttributeError, lambda: mock.__iter__)
mock.__iter__ = Mock(return_value=iter([]))
self.assertEqual(list(mock), [])
class NonIterable(object):
pass
mock = Mock(spec_set=NonIterable)
self.assertRaises(AttributeError, lambda: mock.__iter__)
def set_int():
mock.__int__ = Mock(return_value=iter([]))
self.assertRaises(AttributeError, set_int)
mock = MagicMock(spec_set=Iterable)
self.assertEqual(list(mock), [])
self.assertRaises(AttributeError, set_int)
def test_setting_unsupported_magic_method(self):
mock = MagicMock()
def set_setattr():
mock.__setattr__ = lambda self, name: None
self.assertRaisesRegex(AttributeError,
"Attempting to set unsupported magic method '__setattr__'.",
set_setattr
)
def test_attributes_and_return_value(self):
mock = MagicMock()
attr = mock.foo
def _get_type(obj):
# the type of every mock (or magicmock) is a custom subclass
# so the real type is the second in the mro
return type(obj).__mro__[1]
self.assertEqual(_get_type(attr), MagicMock)
returned = mock()
self.assertEqual(_get_type(returned), MagicMock)
def test_magic_methods_are_magic_mocks(self):
mock = MagicMock()
self.assertIsInstance(mock.__getitem__, MagicMock)
mock[1][2].__getitem__.return_value = 3
self.assertEqual(mock[1][2][3], 3)
def test_magic_method_reset_mock(self):
mock = MagicMock()
str(mock)
self.assertTrue(mock.__str__.called)
mock.reset_mock()
self.assertFalse(mock.__str__.called)
def test_dir(self):
# overriding the default implementation
for mock in Mock(), MagicMock():
def _dir(self):
return ['foo']
mock.__dir__ = _dir
self.assertEqual(dir(mock), ['foo'])
def test_bound_methods(self):
m = Mock()
# XXXX should this be an expected failure instead?
# this seems like it should work, but is hard to do without introducing
# other api inconsistencies. Failure message could be better though.
m.__iter__ = [3].__iter__
self.assertRaises(TypeError, iter, m)
def test_magic_method_type(self):
class Foo(MagicMock):
pass
foo = Foo()
self.assertIsInstance(foo.__int__, Foo)
def test_descriptor_from_class(self):
m = MagicMock()
type(m).__str__.return_value = 'foo'
self.assertEqual(str(m), 'foo')
def test_iterable_as_iter_return_value(self):
m = MagicMock()
m.__iter__.return_value = [1, 2, 3]
self.assertEqual(list(m), [1, 2, 3])
self.assertEqual(list(m), [1, 2, 3])
m.__iter__.return_value = iter([4, 5, 6])
self.assertEqual(list(m), [4, 5, 6])
self.assertEqual(list(m), [])
def test_matmul(self):
m = MagicMock()
self.assertIsInstance(m @ 1, MagicMock)
m.__matmul__.return_value = 42
m.__rmatmul__.return_value = 666
m.__imatmul__.return_value = 24
self.assertEqual(m @ 1, 42)
self.assertEqual(1 @ m, 666)
m @= 24
self.assertEqual(m, 24)
def test_divmod_and_rdivmod(self):
m = MagicMock()
self.assertIsInstance(divmod(5, m), MagicMock)
m.__divmod__.return_value = (2, 1)
self.assertEqual(divmod(m, 2), (2, 1))
m = MagicMock()
foo = divmod(2, m)
self.assertIsInstance(foo, MagicMock)
foo_direct = m.__divmod__(2)
self.assertIsInstance(foo_direct, MagicMock)
bar = divmod(m, 2)
self.assertIsInstance(bar, MagicMock)
bar_direct = m.__rdivmod__(2)
self.assertIsInstance(bar_direct, MagicMock)
# http://bugs.python.org/issue23310
# Check if you can change behaviour of magic methods in MagicMock init
def test_magic_in_initialization(self):
m = MagicMock(**{'__str__.return_value': "12"})
self.assertEqual(str(m), "12")
def test_changing_magic_set_in_initialization(self):
m = MagicMock(**{'__str__.return_value': "12"})
m.__str__.return_value = "13"
self.assertEqual(str(m), "13")
m = MagicMock(**{'__str__.return_value': "12"})
m.configure_mock(**{'__str__.return_value': "14"})
self.assertEqual(str(m), "14")
if __name__ == '__main__':
unittest.main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,237 @@
import unittest
from unittest import mock
class SampleObject:
def method_sample1(self): pass
def method_sample2(self): pass
class TestSealable(unittest.TestCase):
def test_attributes_return_more_mocks_by_default(self):
m = mock.Mock()
self.assertIsInstance(m.test, mock.Mock)
self.assertIsInstance(m.test(), mock.Mock)
self.assertIsInstance(m.test().test2(), mock.Mock)
def test_new_attributes_cannot_be_accessed_on_seal(self):
m = mock.Mock()
mock.seal(m)
with self.assertRaises(AttributeError):
m.test
with self.assertRaises(AttributeError):
m()
def test_new_attributes_cannot_be_set_on_seal(self):
m = mock.Mock()
mock.seal(m)
with self.assertRaises(AttributeError):
m.test = 1
def test_existing_attributes_can_be_set_on_seal(self):
m = mock.Mock()
m.test.test2 = 1
mock.seal(m)
m.test.test2 = 2
self.assertEqual(m.test.test2, 2)
def test_new_attributes_cannot_be_set_on_child_of_seal(self):
m = mock.Mock()
m.test.test2 = 1
mock.seal(m)
with self.assertRaises(AttributeError):
m.test.test3 = 1
def test_existing_attributes_allowed_after_seal(self):
m = mock.Mock()
m.test.return_value = 3
mock.seal(m)
self.assertEqual(m.test(), 3)
def test_initialized_attributes_allowed_after_seal(self):
m = mock.Mock(test_value=1)
mock.seal(m)
self.assertEqual(m.test_value, 1)
def test_call_on_sealed_mock_fails(self):
m = mock.Mock()
mock.seal(m)
with self.assertRaises(AttributeError):
m()
def test_call_on_defined_sealed_mock_succeeds(self):
m = mock.Mock(return_value=5)
mock.seal(m)
self.assertEqual(m(), 5)
def test_seals_recurse_on_added_attributes(self):
m = mock.Mock()
m.test1.test2().test3 = 4
mock.seal(m)
self.assertEqual(m.test1.test2().test3, 4)
with self.assertRaises(AttributeError):
m.test1.test2().test4
with self.assertRaises(AttributeError):
m.test1.test3
def test_seals_recurse_on_magic_methods(self):
m = mock.MagicMock()
m.test1.test2["a"].test3 = 4
m.test1.test3[2:5].test3 = 4
mock.seal(m)
self.assertEqual(m.test1.test2["a"].test3, 4)
self.assertEqual(m.test1.test2[2:5].test3, 4)
with self.assertRaises(AttributeError):
m.test1.test2["a"].test4
with self.assertRaises(AttributeError):
m.test1.test3[2:5].test4
def test_seals_dont_recurse_on_manual_attributes(self):
m = mock.Mock(name="root_mock")
m.test1.test2 = mock.Mock(name="not_sealed")
m.test1.test2.test3 = 4
mock.seal(m)
self.assertEqual(m.test1.test2.test3, 4)
m.test1.test2.test4 # Does not raise
m.test1.test2.test4 = 1 # Does not raise
def test_integration_with_spec_att_definition(self):
"""You are not restricted when using mock with spec"""
m = mock.Mock(SampleObject)
m.attr_sample1 = 1
m.attr_sample3 = 3
mock.seal(m)
self.assertEqual(m.attr_sample1, 1)
self.assertEqual(m.attr_sample3, 3)
with self.assertRaises(AttributeError):
m.attr_sample2
def test_integration_with_spec_method_definition(self):
"""You need to define the methods, even if they are in the spec"""
m = mock.Mock(SampleObject)
m.method_sample1.return_value = 1
mock.seal(m)
self.assertEqual(m.method_sample1(), 1)
with self.assertRaises(AttributeError):
m.method_sample2()
def test_integration_with_spec_method_definition_respects_spec(self):
"""You cannot define methods out of the spec"""
m = mock.Mock(SampleObject)
with self.assertRaises(AttributeError):
m.method_sample3.return_value = 3
def test_sealed_exception_has_attribute_name(self):
m = mock.Mock()
mock.seal(m)
with self.assertRaises(AttributeError) as cm:
m.SECRETE_name
self.assertIn("SECRETE_name", str(cm.exception))
def test_attribute_chain_is_maintained(self):
m = mock.Mock(name="mock_name")
m.test1.test2.test3.test4
mock.seal(m)
with self.assertRaises(AttributeError) as cm:
m.test1.test2.test3.test4.boom
self.assertIn("mock_name.test1.test2.test3.test4.boom", str(cm.exception))
def test_call_chain_is_maintained(self):
m = mock.Mock()
m.test1().test2.test3().test4
mock.seal(m)
with self.assertRaises(AttributeError) as cm:
m.test1().test2.test3().test4()
self.assertIn("mock.test1().test2.test3().test4", str(cm.exception))
def test_seal_with_autospec(self):
# https://bugs.python.org/issue45156
class Foo:
foo = 0
def bar1(self): pass
def bar2(self): pass
class Baz:
baz = 3
def ban(self): pass
for spec_set in (True, False):
with self.subTest(spec_set=spec_set):
foo = mock.create_autospec(Foo, spec_set=spec_set)
foo.bar1.return_value = 'a'
foo.Baz.ban.return_value = 'b'
mock.seal(foo)
self.assertIsInstance(foo.foo, mock.NonCallableMagicMock)
self.assertIsInstance(foo.bar1, mock.MagicMock)
self.assertIsInstance(foo.bar2, mock.MagicMock)
self.assertIsInstance(foo.Baz, mock.MagicMock)
self.assertIsInstance(foo.Baz.baz, mock.NonCallableMagicMock)
self.assertIsInstance(foo.Baz.ban, mock.MagicMock)
# see gh-91803
self.assertIsInstance(foo.bar2(), mock.MagicMock)
self.assertEqual(foo.bar1(), 'a')
foo.bar1.return_value = 'new_a'
self.assertEqual(foo.bar1(), 'new_a')
self.assertEqual(foo.Baz.ban(), 'b')
foo.Baz.ban.return_value = 'new_b'
self.assertEqual(foo.Baz.ban(), 'new_b')
with self.assertRaises(TypeError):
foo.foo()
with self.assertRaises(AttributeError):
foo.bar = 1
with self.assertRaises(AttributeError):
foo.bar2().x
foo.bar2.return_value = 'bar2'
self.assertEqual(foo.bar2(), 'bar2')
with self.assertRaises(AttributeError):
foo.missing_attr
with self.assertRaises(AttributeError):
foo.missing_attr = 1
with self.assertRaises(AttributeError):
foo.missing_method()
with self.assertRaises(TypeError):
foo.Baz.baz()
with self.assertRaises(AttributeError):
foo.Baz.missing_attr
with self.assertRaises(AttributeError):
foo.Baz.missing_attr = 1
with self.assertRaises(AttributeError):
foo.Baz.missing_method()
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,41 @@
import unittest
import copy
import pickle
from unittest.mock import sentinel, DEFAULT
class SentinelTest(unittest.TestCase):
def testSentinels(self):
self.assertEqual(sentinel.whatever, sentinel.whatever,
'sentinel not stored')
self.assertNotEqual(sentinel.whatever, sentinel.whateverelse,
'sentinel should be unique')
def testSentinelName(self):
self.assertEqual(str(sentinel.whatever), 'sentinel.whatever',
'sentinel name incorrect')
def testDEFAULT(self):
self.assertIs(DEFAULT, sentinel.DEFAULT)
def testBases(self):
# If this doesn't raise an AttributeError then help(mock) is broken
self.assertRaises(AttributeError, lambda: sentinel.__bases__)
def testPickle(self):
for proto in range(pickle.HIGHEST_PROTOCOL+1):
with self.subTest(protocol=proto):
pickled = pickle.dumps(sentinel.whatever, proto)
unpickled = pickle.loads(pickled)
self.assertIs(unpickled, sentinel.whatever)
def testCopy(self):
self.assertIs(copy.copy(sentinel.whatever), sentinel.whatever)
self.assertIs(copy.deepcopy(sentinel.whatever), sentinel.whatever)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,201 @@
import time
import unittest
import concurrent.futures
from test.support import threading_helper
from unittest.mock import patch, ThreadingMock
threading_helper.requires_working_threading(module=True)
VERY_SHORT_TIMEOUT = 0.1
class Something:
def method_1(self):
pass # pragma: no cover
def method_2(self):
pass # pragma: no cover
class TestThreadingMock(unittest.TestCase):
def _call_after_delay(self, func, /, *args, **kwargs):
time.sleep(kwargs.pop("delay"))
func(*args, **kwargs)
def setUp(self):
self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=5)
def tearDown(self):
self._executor.shutdown()
def run_async(self, func, /, *args, delay=0, **kwargs):
self._executor.submit(
self._call_after_delay, func, *args, **kwargs, delay=delay
)
def _make_mock(self, *args, **kwargs):
return ThreadingMock(*args, **kwargs)
def test_spec(self):
waitable_mock = self._make_mock(spec=Something)
with patch(f"{__name__}.Something", waitable_mock) as m:
something = m()
self.assertIsInstance(something.method_1, ThreadingMock)
self.assertIsInstance(something.method_1().method_2(), ThreadingMock)
with self.assertRaises(AttributeError):
m.test
def test_side_effect(self):
waitable_mock = self._make_mock()
with patch(f"{__name__}.Something", waitable_mock):
something = Something()
something.method_1.side_effect = [1]
self.assertEqual(something.method_1(), 1)
def test_instance_check(self):
waitable_mock = self._make_mock()
with patch(f"{__name__}.Something", waitable_mock):
something = Something()
self.assertIsInstance(something.method_1, ThreadingMock)
self.assertIsInstance(something.method_1().method_2(), ThreadingMock)
def test_dynamic_child_mocks_are_threading_mocks(self):
waitable_mock = self._make_mock()
self.assertIsInstance(waitable_mock.child, ThreadingMock)
def test_dynamic_child_mocks_inherit_timeout(self):
mock1 = self._make_mock()
self.assertIs(mock1._mock_wait_timeout, None)
mock2 = self._make_mock(timeout=2)
self.assertEqual(mock2._mock_wait_timeout, 2)
mock3 = self._make_mock(timeout=3)
self.assertEqual(mock3._mock_wait_timeout, 3)
self.assertIs(mock1.child._mock_wait_timeout, None)
self.assertEqual(mock2.child._mock_wait_timeout, 2)
self.assertEqual(mock3.child._mock_wait_timeout, 3)
self.assertEqual(mock2.really().__mul__().complex._mock_wait_timeout, 2)
def test_no_name_clash(self):
waitable_mock = self._make_mock()
waitable_mock._event = "myevent"
waitable_mock.event = "myevent"
waitable_mock.timeout = "mytimeout"
waitable_mock("works")
waitable_mock.wait_until_called()
waitable_mock.wait_until_any_call_with("works")
def test_patch(self):
waitable_mock = self._make_mock(spec=Something)
with patch(f"{__name__}.Something", waitable_mock):
something = Something()
something.method_1()
something.method_1.wait_until_called()
def test_wait_already_called_success(self):
waitable_mock = self._make_mock(spec=Something)
waitable_mock.method_1()
waitable_mock.method_1.wait_until_called()
waitable_mock.method_1.wait_until_any_call_with()
waitable_mock.method_1.assert_called()
def test_wait_until_called_success(self):
waitable_mock = self._make_mock(spec=Something)
self.run_async(waitable_mock.method_1, delay=VERY_SHORT_TIMEOUT)
waitable_mock.method_1.wait_until_called()
def test_wait_until_called_method_timeout(self):
waitable_mock = self._make_mock(spec=Something)
with self.assertRaises(AssertionError):
waitable_mock.method_1.wait_until_called(timeout=VERY_SHORT_TIMEOUT)
def test_wait_until_called_instance_timeout(self):
waitable_mock = self._make_mock(spec=Something, timeout=VERY_SHORT_TIMEOUT)
with self.assertRaises(AssertionError):
waitable_mock.method_1.wait_until_called()
def test_wait_until_called_global_timeout(self):
with patch.object(ThreadingMock, "DEFAULT_TIMEOUT"):
ThreadingMock.DEFAULT_TIMEOUT = VERY_SHORT_TIMEOUT
waitable_mock = self._make_mock(spec=Something)
with self.assertRaises(AssertionError):
waitable_mock.method_1.wait_until_called()
def test_wait_until_any_call_with_success(self):
waitable_mock = self._make_mock()
self.run_async(waitable_mock, delay=VERY_SHORT_TIMEOUT)
waitable_mock.wait_until_any_call_with()
def test_wait_until_any_call_with_instance_timeout(self):
waitable_mock = self._make_mock(timeout=VERY_SHORT_TIMEOUT)
with self.assertRaises(AssertionError):
waitable_mock.wait_until_any_call_with()
def test_wait_until_any_call_global_timeout(self):
with patch.object(ThreadingMock, "DEFAULT_TIMEOUT"):
ThreadingMock.DEFAULT_TIMEOUT = VERY_SHORT_TIMEOUT
waitable_mock = self._make_mock()
with self.assertRaises(AssertionError):
waitable_mock.wait_until_any_call_with()
def test_wait_until_any_call_positional(self):
waitable_mock = self._make_mock(timeout=VERY_SHORT_TIMEOUT)
waitable_mock.method_1(1, 2, 3)
waitable_mock.method_1.wait_until_any_call_with(1, 2, 3)
with self.assertRaises(AssertionError):
waitable_mock.method_1.wait_until_any_call_with(2, 3, 1)
with self.assertRaises(AssertionError):
waitable_mock.method_1.wait_until_any_call_with()
def test_wait_until_any_call_kw(self):
waitable_mock = self._make_mock(timeout=VERY_SHORT_TIMEOUT)
waitable_mock.method_1(a=1, b=2)
waitable_mock.method_1.wait_until_any_call_with(a=1, b=2)
with self.assertRaises(AssertionError):
waitable_mock.method_1.wait_until_any_call_with(a=2, b=1)
with self.assertRaises(AssertionError):
waitable_mock.method_1.wait_until_any_call_with()
def test_magic_methods_success(self):
waitable_mock = self._make_mock()
str(waitable_mock)
waitable_mock.__str__.wait_until_called()
waitable_mock.__str__.assert_called()
def test_reset_mock_resets_wait(self):
m = self._make_mock(timeout=VERY_SHORT_TIMEOUT)
with self.assertRaises(AssertionError):
m.wait_until_called()
with self.assertRaises(AssertionError):
m.wait_until_any_call_with()
m()
m.wait_until_called()
m.wait_until_any_call_with()
m.assert_called_once()
m.reset_mock()
with self.assertRaises(AssertionError):
m.wait_until_called()
with self.assertRaises(AssertionError):
m.wait_until_any_call_with()
m()
m.wait_until_called()
m.wait_until_any_call_with()
m.assert_called_once()
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,347 @@
import unittest
from warnings import catch_warnings
from test.test_unittest.testmock.support import is_instance
from unittest.mock import MagicMock, Mock, patch, sentinel, mock_open, call
something = sentinel.Something
something_else = sentinel.SomethingElse
class SampleException(Exception): pass
class WithTest(unittest.TestCase):
def test_with_statement(self):
with patch('%s.something' % __name__, sentinel.Something2):
self.assertEqual(something, sentinel.Something2, "unpatched")
self.assertEqual(something, sentinel.Something)
def test_with_statement_exception(self):
with self.assertRaises(SampleException):
with patch('%s.something' % __name__, sentinel.Something2):
self.assertEqual(something, sentinel.Something2, "unpatched")
raise SampleException()
self.assertEqual(something, sentinel.Something)
def test_with_statement_as(self):
with patch('%s.something' % __name__) as mock_something:
self.assertEqual(something, mock_something, "unpatched")
self.assertTrue(is_instance(mock_something, MagicMock),
"patching wrong type")
self.assertEqual(something, sentinel.Something)
def test_patch_object_with_statement(self):
class Foo(object):
something = 'foo'
original = Foo.something
with patch.object(Foo, 'something'):
self.assertNotEqual(Foo.something, original, "unpatched")
self.assertEqual(Foo.something, original)
def test_with_statement_nested(self):
with catch_warnings(record=True):
with patch('%s.something' % __name__) as mock_something, patch('%s.something_else' % __name__) as mock_something_else:
self.assertEqual(something, mock_something, "unpatched")
self.assertEqual(something_else, mock_something_else,
"unpatched")
self.assertEqual(something, sentinel.Something)
self.assertEqual(something_else, sentinel.SomethingElse)
def test_with_statement_specified(self):
with patch('%s.something' % __name__, sentinel.Patched) as mock_something:
self.assertEqual(something, mock_something, "unpatched")
self.assertEqual(mock_something, sentinel.Patched, "wrong patch")
self.assertEqual(something, sentinel.Something)
def testContextManagerMocking(self):
mock = Mock()
mock.__enter__ = Mock()
mock.__exit__ = Mock()
mock.__exit__.return_value = False
with mock as m:
self.assertEqual(m, mock.__enter__.return_value)
mock.__enter__.assert_called_with()
mock.__exit__.assert_called_with(None, None, None)
def test_context_manager_with_magic_mock(self):
mock = MagicMock()
with self.assertRaises(TypeError):
with mock:
'foo' + 3
mock.__enter__.assert_called_with()
self.assertTrue(mock.__exit__.called)
def test_with_statement_same_attribute(self):
with patch('%s.something' % __name__, sentinel.Patched) as mock_something:
self.assertEqual(something, mock_something, "unpatched")
with patch('%s.something' % __name__) as mock_again:
self.assertEqual(something, mock_again, "unpatched")
self.assertEqual(something, mock_something,
"restored with wrong instance")
self.assertEqual(something, sentinel.Something, "not restored")
def test_with_statement_imbricated(self):
with patch('%s.something' % __name__) as mock_something:
self.assertEqual(something, mock_something, "unpatched")
with patch('%s.something_else' % __name__) as mock_something_else:
self.assertEqual(something_else, mock_something_else,
"unpatched")
self.assertEqual(something, sentinel.Something)
self.assertEqual(something_else, sentinel.SomethingElse)
def test_dict_context_manager(self):
foo = {}
with patch.dict(foo, {'a': 'b'}):
self.assertEqual(foo, {'a': 'b'})
self.assertEqual(foo, {})
with self.assertRaises(NameError):
with patch.dict(foo, {'a': 'b'}):
self.assertEqual(foo, {'a': 'b'})
raise NameError('Konrad')
self.assertEqual(foo, {})
def test_double_patch_instance_method(self):
class C:
def f(self): pass
c = C()
with patch.object(c, 'f') as patch1:
with patch.object(c, 'f') as patch2:
c.f()
self.assertEqual(patch2.call_count, 1)
self.assertEqual(patch1.call_count, 0)
c.f()
self.assertEqual(patch1.call_count, 1)
class TestMockOpen(unittest.TestCase):
def test_mock_open(self):
mock = mock_open()
with patch('%s.open' % __name__, mock, create=True) as patched:
self.assertIs(patched, mock)
open('foo')
mock.assert_called_once_with('foo')
def test_mock_open_context_manager(self):
mock = mock_open()
handle = mock.return_value
with patch('%s.open' % __name__, mock, create=True):
with open('foo') as f:
f.read()
expected_calls = [call('foo'), call().__enter__(), call().read(),
call().__exit__(None, None, None), call().close()]
self.assertEqual(mock.mock_calls, expected_calls)
self.assertIs(f, handle)
def test_mock_open_context_manager_multiple_times(self):
mock = mock_open()
with patch('%s.open' % __name__, mock, create=True):
with open('foo') as f:
f.read()
with open('bar') as f:
f.read()
expected_calls = [
call('foo'), call().__enter__(), call().read(),
call().__exit__(None, None, None), call().close(),
call('bar'), call().__enter__(), call().read(),
call().__exit__(None, None, None), call().close()]
self.assertEqual(mock.mock_calls, expected_calls)
def test_explicit_mock(self):
mock = MagicMock()
mock_open(mock)
with patch('%s.open' % __name__, mock, create=True) as patched:
self.assertIs(patched, mock)
open('foo')
mock.assert_called_once_with('foo')
def test_read_data(self):
mock = mock_open(read_data='foo')
with patch('%s.open' % __name__, mock, create=True):
h = open('bar')
result = h.read()
self.assertEqual(result, 'foo')
def test_readline_data(self):
# Check that readline will return all the lines from the fake file
# And that once fully consumed, readline will return an empty string.
mock = mock_open(read_data='foo\nbar\nbaz\n')
with patch('%s.open' % __name__, mock, create=True):
h = open('bar')
line1 = h.readline()
line2 = h.readline()
line3 = h.readline()
self.assertEqual(line1, 'foo\n')
self.assertEqual(line2, 'bar\n')
self.assertEqual(line3, 'baz\n')
self.assertEqual(h.readline(), '')
# Check that we properly emulate a file that doesn't end in a newline
mock = mock_open(read_data='foo')
with patch('%s.open' % __name__, mock, create=True):
h = open('bar')
result = h.readline()
self.assertEqual(result, 'foo')
self.assertEqual(h.readline(), '')
def test_dunder_iter_data(self):
# Check that dunder_iter will return all the lines from the fake file.
mock = mock_open(read_data='foo\nbar\nbaz\n')
with patch('%s.open' % __name__, mock, create=True):
h = open('bar')
lines = [l for l in h]
self.assertEqual(lines[0], 'foo\n')
self.assertEqual(lines[1], 'bar\n')
self.assertEqual(lines[2], 'baz\n')
self.assertEqual(h.readline(), '')
with self.assertRaises(StopIteration):
next(h)
def test_next_data(self):
# Check that next will correctly return the next available
# line and plays well with the dunder_iter part.
mock = mock_open(read_data='foo\nbar\nbaz\n')
with patch('%s.open' % __name__, mock, create=True):
h = open('bar')
line1 = next(h)
line2 = next(h)
lines = [l for l in h]
self.assertEqual(line1, 'foo\n')
self.assertEqual(line2, 'bar\n')
self.assertEqual(lines[0], 'baz\n')
self.assertEqual(h.readline(), '')
def test_readlines_data(self):
# Test that emulating a file that ends in a newline character works
mock = mock_open(read_data='foo\nbar\nbaz\n')
with patch('%s.open' % __name__, mock, create=True):
h = open('bar')
result = h.readlines()
self.assertEqual(result, ['foo\n', 'bar\n', 'baz\n'])
# Test that files without a final newline will also be correctly
# emulated
mock = mock_open(read_data='foo\nbar\nbaz')
with patch('%s.open' % __name__, mock, create=True):
h = open('bar')
result = h.readlines()
self.assertEqual(result, ['foo\n', 'bar\n', 'baz'])
def test_read_bytes(self):
mock = mock_open(read_data=b'\xc6')
with patch('%s.open' % __name__, mock, create=True):
with open('abc', 'rb') as f:
result = f.read()
self.assertEqual(result, b'\xc6')
def test_readline_bytes(self):
m = mock_open(read_data=b'abc\ndef\nghi\n')
with patch('%s.open' % __name__, m, create=True):
with open('abc', 'rb') as f:
line1 = f.readline()
line2 = f.readline()
line3 = f.readline()
self.assertEqual(line1, b'abc\n')
self.assertEqual(line2, b'def\n')
self.assertEqual(line3, b'ghi\n')
def test_readlines_bytes(self):
m = mock_open(read_data=b'abc\ndef\nghi\n')
with patch('%s.open' % __name__, m, create=True):
with open('abc', 'rb') as f:
result = f.readlines()
self.assertEqual(result, [b'abc\n', b'def\n', b'ghi\n'])
def test_mock_open_read_with_argument(self):
# At one point calling read with an argument was broken
# for mocks returned by mock_open
some_data = 'foo\nbar\nbaz'
mock = mock_open(read_data=some_data)
self.assertEqual(mock().read(10), some_data[:10])
self.assertEqual(mock().read(10), some_data[:10])
f = mock()
self.assertEqual(f.read(10), some_data[:10])
self.assertEqual(f.read(10), some_data[10:])
def test_interleaved_reads(self):
# Test that calling read, readline, and readlines pulls data
# sequentially from the data we preload with
mock = mock_open(read_data='foo\nbar\nbaz\n')
with patch('%s.open' % __name__, mock, create=True):
h = open('bar')
line1 = h.readline()
rest = h.readlines()
self.assertEqual(line1, 'foo\n')
self.assertEqual(rest, ['bar\n', 'baz\n'])
mock = mock_open(read_data='foo\nbar\nbaz\n')
with patch('%s.open' % __name__, mock, create=True):
h = open('bar')
line1 = h.readline()
rest = h.read()
self.assertEqual(line1, 'foo\n')
self.assertEqual(rest, 'bar\nbaz\n')
def test_overriding_return_values(self):
mock = mock_open(read_data='foo')
handle = mock()
handle.read.return_value = 'bar'
handle.readline.return_value = 'bar'
handle.readlines.return_value = ['bar']
self.assertEqual(handle.read(), 'bar')
self.assertEqual(handle.readline(), 'bar')
self.assertEqual(handle.readlines(), ['bar'])
# call repeatedly to check that a StopIteration is not propagated
self.assertEqual(handle.readline(), 'bar')
self.assertEqual(handle.readline(), 'bar')
if __name__ == '__main__':
unittest.main()