self._callMaybeAsync(function, *args, **kwargs)
def _callAsync(self, func, /, *args, **kwargs):
- assert self._asyncioTestLoop is not None
+ assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized'
ret = func(*args, **kwargs)
- assert inspect.isawaitable(ret)
+ assert inspect.isawaitable(ret), f'{func!r} returned non-awaitable'
fut = self._asyncioTestLoop.create_future()
self._asyncioCallsQueue.put_nowait((fut, ret))
return self._asyncioTestLoop.run_until_complete(fut)
def _callMaybeAsync(self, func, /, *args, **kwargs):
- assert self._asyncioTestLoop is not None
+ assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized'
ret = func(*args, **kwargs)
if inspect.isawaitable(ret):
fut = self._asyncioTestLoop.create_future()
fut.set_exception(ex)
def _setupAsyncioLoop(self):
- assert self._asyncioTestLoop is None
+ assert self._asyncioTestLoop is None, 'asyncio test loop already initialized'
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.set_debug(True)
loop.run_until_complete(fut)
def _tearDownAsyncioLoop(self):
- assert self._asyncioTestLoop is not None
+ assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized'
loop = self._asyncioTestLoop
self._asyncioTestLoop = None
self._asyncioCallsQueue.put_nowait(None)
return super().run(result)
finally:
self._tearDownAsyncioLoop()
+
+ def debug(self):
+ self._setupAsyncioLoop()
+ super().debug()
+ self._tearDownAsyncioLoop()
+
+ def __del__(self):
+ if self._asyncioTestLoop is not None:
+ self._tearDownAsyncioLoop()
import asyncio
import unittest
+from test import support
+
+
+class MyException(Exception):
+ pass
def tearDownModule():
class TestAsyncCase(unittest.TestCase):
- def test_full_cycle(self):
- events = []
+ maxDiff = None
+
+ def tearDown(self):
+ # Ensure that IsolatedAsyncioTestCase instances are destroyed before
+ # starting a new event loop
+ support.gc_collect()
+ def test_full_cycle(self):
class Test(unittest.IsolatedAsyncioTestCase):
def setUp(self):
self.assertEqual(events, [])
async def asyncSetUp(self):
self.assertEqual(events, ['setUp'])
events.append('asyncSetUp')
+ self.addAsyncCleanup(self.on_cleanup1)
async def test_func(self):
self.assertEqual(events, ['setUp',
'asyncSetUp'])
events.append('test')
- self.addAsyncCleanup(self.on_cleanup)
+ self.addAsyncCleanup(self.on_cleanup2)
async def asyncTearDown(self):
self.assertEqual(events, ['setUp',
'asyncTearDown'])
events.append('tearDown')
- async def on_cleanup(self):
+ async def on_cleanup1(self):
+ self.assertEqual(events, ['setUp',
+ 'asyncSetUp',
+ 'test',
+ 'asyncTearDown',
+ 'tearDown',
+ 'cleanup2'])
+ events.append('cleanup1')
+
+ async def on_cleanup2(self):
self.assertEqual(events, ['setUp',
'asyncSetUp',
'test',
'asyncTearDown',
'tearDown'])
- events.append('cleanup')
+ events.append('cleanup2')
+ events = []
test = Test("test_func")
- test.run()
- self.assertEqual(events, ['setUp',
- 'asyncSetUp',
- 'test',
- 'asyncTearDown',
- 'tearDown',
- 'cleanup'])
+ result = test.run()
+ self.assertEqual(result.errors, [])
+ self.assertEqual(result.failures, [])
+ expected = ['setUp', 'asyncSetUp', 'test',
+ 'asyncTearDown', 'tearDown', 'cleanup2', 'cleanup1']
+ self.assertEqual(events, expected)
- def test_exception_in_setup(self):
events = []
+ test = Test("test_func")
+ test.debug()
+ self.assertEqual(events, expected)
+ test.doCleanups()
+ self.assertEqual(events, expected)
+ def test_exception_in_setup(self):
class Test(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
events.append('asyncSetUp')
- raise Exception()
+ self.addAsyncCleanup(self.on_cleanup)
+ raise MyException()
async def test_func(self):
events.append('test')
- self.addAsyncCleanup(self.on_cleanup)
async def asyncTearDown(self):
events.append('asyncTearDown')
events.append('cleanup')
+ events = []
test = Test("test_func")
- test.run()
- self.assertEqual(events, ['asyncSetUp'])
+ result = test.run()
+ self.assertEqual(events, ['asyncSetUp', 'cleanup'])
+ self.assertIs(result.errors[0][0], test)
+ self.assertIn('MyException', result.errors[0][1])
- def test_exception_in_test(self):
events = []
+ test = Test("test_func")
+ 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')
- raise Exception()
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")
- test.run()
- self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown'])
+ result = test.run()
+ self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup'])
+ self.assertIs(result.errors[0][0], test)
+ self.assertIn('MyException', result.errors[0][1])
- def test_exception_in_test_after_adding_cleanup(self):
events = []
+ test = Test("test_func")
+ 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)
- raise Exception()
async def asyncTearDown(self):
events.append('asyncTearDown')
+ raise MyException()
async def on_cleanup(self):
events.append('cleanup')
+ events = []
test = Test("test_func")
- test.run()
+ result = test.run()
self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup'])
+ self.assertIs(result.errors[0][0], test)
+ self.assertIn('MyException', result.errors[0][1])
- def test_exception_in_tear_down(self):
events = []
-
- 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 Exception()
-
- async def on_cleanup(self):
- events.append('cleanup')
-
test = Test("test_func")
- test.run()
+ 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):
- events = []
-
class Test(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
events.append('asyncSetUp')
async def test_func(self):
events.append('test')
- self.addAsyncCleanup(self.on_cleanup)
+ self.addAsyncCleanup(self.on_cleanup1)
+ self.addAsyncCleanup(self.on_cleanup2)
async def asyncTearDown(self):
events.append('asyncTearDown')
- async def on_cleanup(self):
- events.append('cleanup')
- raise Exception()
+ 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")
- test.run()
- self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup'])
+ 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")
+ 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_cleanups_interleave_order(self):
events = []
self.assertFalse(output.wasSuccessful())
-
if __name__ == "__main__":
unittest.main()