mirror of
https://github.com/python/cpython.git
synced 2025-09-25 17:59:57 +00:00
bpo-32972: Document IsolatedAsyncioTestCase of unittest module (GH-15878) (GH-15918)
* Document `unittest.IsolatedAsyncioTestCase` API
* Add a simple example with respect to order of evaluation of setup and teardown calls.
https://bugs.python.org/issue32972
Automerge-Triggered-By: @asvetlov
(cherry picked from commit 6a9fd66f6e
)
Co-authored-by: Xtreak <tir.karthi@gmail.com>
This commit is contained in:
parent
7acb22e6e9
commit
0ba5dbd992
3 changed files with 103 additions and 1 deletions
|
@ -1486,8 +1486,84 @@ Test cases
|
||||||
.. versionadded:: 3.8
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
|
||||||
|
.. class:: IsolatedAsyncioTestCase(methodName='runTest')
|
||||||
|
|
||||||
|
This class provides an API similar to :class:`TestCase` and also accepts
|
||||||
|
coroutines as test functions.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
.. coroutinemethod:: asyncSetUp()
|
||||||
|
|
||||||
|
Method called to prepare the test fixture. This is called after :meth:`setUp`.
|
||||||
|
This is called immediately before calling the test method; other than
|
||||||
|
:exc:`AssertionError` or :exc:`SkipTest`, any exception raised by this method
|
||||||
|
will be considered an error rather than a test failure. The default implementation
|
||||||
|
does nothing.
|
||||||
|
|
||||||
|
.. coroutinemethod:: asyncTearDown()
|
||||||
|
|
||||||
|
Method called immediately after the test method has been called and the
|
||||||
|
result recorded. This is called before :meth:`tearDown`. This is called even if
|
||||||
|
the test method raised an exception, so the implementation in subclasses may need
|
||||||
|
to be particularly careful about checking internal state. Any exception, other than
|
||||||
|
:exc:`AssertionError` or :exc:`SkipTest`, raised by this method will be
|
||||||
|
considered an additional error rather than a test failure (thus increasing
|
||||||
|
the total number of reported errors). This method will only be called if
|
||||||
|
the :meth:`asyncSetUp` succeeds, regardless of the outcome of the test method.
|
||||||
|
The default implementation does nothing.
|
||||||
|
|
||||||
|
.. method:: addAsyncCleanup(function, /, *args, **kwargs)
|
||||||
|
|
||||||
|
This method accepts a coroutine that can be used as a cleanup function.
|
||||||
|
|
||||||
|
.. method:: run(result=None)
|
||||||
|
|
||||||
|
Sets up a new event loop to run the test, collecting the result into
|
||||||
|
the :class:`TestResult` object passed as *result*. If *result* is
|
||||||
|
omitted or ``None``, a temporary result object is created (by calling
|
||||||
|
the :meth:`defaultTestResult` method) and used. The result object is
|
||||||
|
returned to :meth:`run`'s caller. At the end of the test all the tasks
|
||||||
|
in the event loop are cancelled.
|
||||||
|
|
||||||
|
|
||||||
|
An example illustrating the order::
|
||||||
|
|
||||||
|
from unittest import IsolatedAsyncioTestCase
|
||||||
|
|
||||||
|
events = []
|
||||||
|
|
||||||
|
|
||||||
|
class Test(IsolatedAsyncioTestCase):
|
||||||
|
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
events.append("setUp")
|
||||||
|
|
||||||
|
async def asyncSetUp(self):
|
||||||
|
self._async_connection = await AsyncConnection()
|
||||||
|
events.append("asyncSetUp")
|
||||||
|
|
||||||
|
async def test_response(self):
|
||||||
|
events.append("test_response")
|
||||||
|
response = await self._async_connection.get("https://example.com")
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.addAsyncCleanup(self.on_cleanup)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
events.append("tearDown")
|
||||||
|
|
||||||
|
async def asyncTearDown(self):
|
||||||
|
await self._async_connection.close()
|
||||||
|
events.append("asyncTearDown")
|
||||||
|
|
||||||
|
async def on_cleanup(self):
|
||||||
|
events.append("cleanup")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
|
|
||||||
|
After running the test ``events`` would contain ``["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"]``
|
||||||
|
|
||||||
|
|
||||||
.. class:: FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)
|
.. class:: FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)
|
||||||
|
|
|
@ -1111,6 +1111,32 @@ unittest
|
||||||
* Several mock assert functions now also print a list of actual calls upon
|
* Several mock assert functions now also print a list of actual calls upon
|
||||||
failure. (Contributed by Petter Strandmark in :issue:`35047`.)
|
failure. (Contributed by Petter Strandmark in :issue:`35047`.)
|
||||||
|
|
||||||
|
* :mod:`unittest` module gained support for coroutines to be used as test cases
|
||||||
|
with :class:`unittest.IsolatedAsyncioTestCase`.
|
||||||
|
(Contributed by Andrew Svetlov in :issue:`32972`.)
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
class TestRequest(unittest.IsolatedAsyncioTestCase):
|
||||||
|
|
||||||
|
async def asyncSetUp(self):
|
||||||
|
self.connection = await AsyncConnection()
|
||||||
|
|
||||||
|
async def test_get(self):
|
||||||
|
response = await self.connection.get("https://example.com")
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
async def asyncTearDown(self):
|
||||||
|
await self.connection.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
|
|
||||||
|
|
||||||
venv
|
venv
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
|
@ -808,7 +808,7 @@ detect classes that can be passed to `hex()`, `oct()` and `bin()`.
|
||||||
.. nonce: LoeUNh
|
.. nonce: LoeUNh
|
||||||
.. section: Library
|
.. section: Library
|
||||||
|
|
||||||
Implement ``unittest.AsyncTestCase`` to help testing asyncio-based code.
|
Implement ``unittest.IsolatedAsyncioTestCase`` to help testing asyncio-based code.
|
||||||
|
|
||||||
..
|
..
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue