asynctest
asynctest is a Python library that enhances the standard `unittest` package with features tailored for testing `asyncio` applications. It reduces boilerplate by providing `TestCase` subclasses and mock objects designed to work seamlessly with coroutines and event loops. While built on `unittest`, it overrides and adds features for asynchronous testing, currently targeting the 'selector' model. The current version is 0.13.0, and its release cadence has been infrequent, indicating a maintenance status.
Warnings
- breaking Python 3.4 is no longer supported since asynctest 0.13.0. Importing the library on Python 3.4 will raise a SyntaxError.
- breaking The behavior of `@patch` decorators for coroutines changed in asynctest 0.13.0. Previously, the mock object was re-used for each call of the coroutine, which was inconsistent with `unittest.patch`.
- gotcha asynctest currently targets the 'selector' model for event loops. Some features may not work as expected or at all with Windows' 'proactor' event loop policy.
- deprecated Internal usage of the `@asyncio.coroutine` decorator within asynctest's mock module may trigger `DeprecationWarning` in Python 3.8+ (where `async def` is preferred). While tests may still run, it indicates reliance on deprecated asyncio features.
- gotcha Forgetting to `await` asynchronous calls within `async def` test methods, `setUp`, or `tearDown` can lead to coroutines not running or tests passing unexpectedly without verifying the asynchronous operation's completion.
- gotcha Setting `TestCase.use_default_loop = True` to share a single event loop across multiple tests can lead to unpredictable test states and side effects, as tasks or callbacks from previous tests might interfere with subsequent ones.
Install
-
pip install asynctest
Imports
- TestCase
from asynctest import TestCase
- CoroutineMock
from asynctest.mock import CoroutineMock
- patch
from asynctest.mock import patch
Quickstart
import asynctest
import asyncio
class MyAsyncTest(asynctest.TestCase):
async def my_async_function(self):
# Simulate an asynchronous operation
await asyncio.sleep(0.001)
return "async_result"
async def test_my_async_method(self):
result = await self.my_async_function()
self.assertEqual(result, "async_result")
async def test_with_coroutine_mock(self):
mock_return = "mocked_async_data"
my_mock = asynctest.CoroutineMock(return_value=mock_return)
# Call the mocked coroutine
data = await my_mock()
self.assertEqual(data, mock_return)
my_mock.assert_awaited_once()
# To run these tests, save the file (e.g., test_my_module.py) and run:
# python -m unittest test_my_module.py
# asynctest.main() can also be used if explicitly desired, but unittest discovery works.