Test python asyncio-based code with ease.

Overview

aiounittest

image0 image1

Info

The aiounittest is a helper library to ease of your pain (and boilerplate), when writing a test of the asynchronous code (asyncio). You can test:

  • synchronous code (same as the unittest.TestCase)
  • asynchronous code, it supports syntax with async/await (Python 3.5+) and asyncio.coroutine/yield from (Python 3.4)

In the Python 3.8 (release note) and newer consider to use the unittest.IsolatedAsyncioTestCase. Builtin unittest module is now asyncio-featured.

Installation

Use pip:

pip install aiounittest

Usage

It's as simple as use of unittest.TestCase. Full docs at http://aiounittest.readthedocs.io.

import asyncio
import aiounittest


async def add(x, y):
    await asyncio.sleep(0.1)
    return x + y

class MyTest(aiounittest.AsyncTestCase):

    async def test_async_add(self):
        ret = await add(5, 6)
        self.assertEqual(ret, 11)

    # or 3.4 way
    @asyncio.coroutine
    def test_sleep(self):
        ret = yield from add(5, 6)
        self.assertEqual(ret, 11)

    # some regular test code
    def test_something(self):
        self.assertTrue(True)

Library provides some additional tooling:

License

MIT

Comments
  • test_sync_async_add: After closing the default event loop, set a new one

    test_sync_async_add: After closing the default event loop, set a new one

    TestAsyncCase.test_sync_async_add leaves the default loop closed. If TestAsyncCaseWithCustomLoop.test_await_async_add runs right after it, it will fail. As far as I can see from the other test methods, the default loop should be reset if it's closed.

    Usually, this issue is masked by tests that run in between these two and re-set the default event loop as a side effect. It can be reproduced with pytest -k 'test_await_async_add or test_sync_async_add', or on Python 3.11 with #21 merged (cc @hroncok).

    opened by encukou 1
  • Re-export top-level imports to satisfy Mypy

    Re-export top-level imports to satisfy Mypy

    Using Mypy (at least in strict mode) with the library as it currently is causes errors.

    import aiounittest
    
    
    class ExampleTest(aiounittest.AsyncTestCase):
        def test_example(self) -> None:
            self.assertEqual(1, 2 - 1)
    
    tests/test_example.py:4: error: Name "aiounittest.AsyncTestCase" is not defined
    tests/test_example.py:4: error: Class cannot subclass "AsyncTestCase" (has type "Any")
    

    It seems to be good practice to 're-export' (using __all__) all the things that you import into a module and wish to allow others to use as an import. I don't think this is actually functionally different, but just a convention. IDEs (auto-import feature) and Mypy pick up on this, at the very least.

    Signed-off-by: Olivier Wilkinson (reivilibre) [email protected] I am happy for these changes to be available under the project's licence (MIT).

    opened by reivilibre 1
  • patch on method/class level

    patch on method/class level

    Hi :)

    class Test(AsyncTestCase):
        @patch('some_path.features_topic.send', new=AsyncMock())
        async def test_smoke(self, mocked_topic):
            ...
    

    I get a TypeError: test_smoke() missing 1 required positional argument: 'mocked_topic'

    If I patch within the test with a with patch(..) as patched_object: it works fine.

    opened by jorotenev 1
  • Event loop is closed after a test but new default event loop is not created

    Event loop is closed after a test but new default event loop is not created

    When running multiple test cases using aiounittest under Python 3.8, the second and all the following unit test cases fail because there is no default event loop set in the MainThread. The following exception is raised when the unit tests are executed.

    Traceback (most recent call last):
      File "lib\site-packages\aiounittest\helpers.py", line 130, in wrapper
        loop = get_brand_new_default_event_loop()
      File "lib\site-packages\aiounittest\helpers.py", line 117, in get_brand_new_default_event_loop
        old_loop = asyncio.get_event_loop()
      File "lib\asyncio\events.py", line 639, in get_event_loop
        raise RuntimeError('There is no current event loop in thread %r.'
    RuntimeError: There is no current event loop in thread 'MainThread'.
    

    This exception occurs because get_brand_new_default_event_loop tries to get the default event loop after it has been closed in the decorator.

    opened by tmaila 1
  • Latest version isn't published to PyPI

    Latest version isn't published to PyPI

    The PyPI version does not check if a test case method is a coroutine, only that it is a callable. This differs from what's in this repo, which I think is the more correct behavior:

        def __getattribute__(self, name):
            attr = super().__getattribute__(name)
            if name.startswith('test_') and callable(attr):
                return async_test(attr, loop=self.get_event_loop())
            else:
                return attr
    
    opened by jcmcken 1
  • setUp and tearDown can't be async

    setUp and tearDown can't be async

    The AsyncTestCase assumes that only methods named test_* can be async, which isn't necessarily a valid assumption. This restriction should be removed, since you already test if the given function is a coroutine.

    opened by jcmcken 1
  • Can't call python -m unittest my_test_module.MyTestCase.test_my_async_test

    Can't call python -m unittest my_test_module.MyTestCase.test_my_async_test

    Can't call one test method directly:

    $ python -m unittest my_test_module.MyTestCase.test_my_async_test
      File ".../unittest/loader.py", line 205, in loadTestsFromName
        test = obj()
    TypeError: test_my_async_test() missing 1 required positional argument: 'self'
    
    

    The reason is that the object given by __getattribute__ is tested against type.MethodType, but async_test(...) is not.

    opened by Alcolo47 0
  • Fixed an issue where RuntimeError was thrown when running multiple tests

    Fixed an issue where RuntimeError was thrown when running multiple tests

    Fixes issue #10: RuntimeError was thrown the decorator trying to get the default event loop after the old event loop was closed. No default event loop existed and the asyncio threw a RuntimeErroe exception.

    opened by tmaila 0
  • mypy / static typing support

    mypy / static typing support

    Right now mypy is not aware that aiounittest subclasses TestCase, which is a bummer for static typing. One has to

    import aiounittest  # type: ignore
    

    which gives it the Any type. Apart from disabling type checking, this also prevents us from turning on mypy --strict mode which includes disallow_subclassing_any = True or the following error ensues:

    tests/test_case.py:15: error: Class cannot subclass 'AsyncTestCase' (has type 'Any')
    

    It seems like we only need to add an empty py.typed marker file as described in https://www.python.org/dev/peps/pep-0561/

    opened by vbraun 0
  • Initial Update

    Initial Update

    The bot created this issue to inform you that pyup.io has been set up on this repo. Once you have closed it, the bot will open pull requests for updates as soon as they are available.

    opened by pyup-bot 0
  • 1.4.1: pytest warnings

    1.4.1: pytest warnings

    Looks like latest pytest shows some warnings

    ============================================================================= warnings summary =============================================================================
    tests/test_asynctestcase.py:41
      /home/tkloczko/rpmbuild/BUILD/aiounittest-1.4.1/tests/test_asynctestcase.py:41: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
        def test_yield_async_add(self):
    
    tests/test_asynctestcase.py:56
      /home/tkloczko/rpmbuild/BUILD/aiounittest-1.4.1/tests/test_asynctestcase.py:56: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
        def test_yield_async_add(self):
    
    tests/test_asynctestcase_get_event_loop.py:38
      /home/tkloczko/rpmbuild/BUILD/aiounittest-1.4.1/tests/test_asynctestcase_get_event_loop.py:38: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
        def test_yield_async_add(self):
    
    -- Docs: https://docs.pytest.org/en/stable/warnings.html
    
    opened by kloczek 0
Releases(1.4.2)
  • 1.4.2(Jun 13, 2022)

    What's Changed

    • Don't run @asyncio.coroutine tests with Python 3.11 by @hroncok in https://github.com/kwarunek/aiounittest/pull/21
    • test_sync_async_add: After closing the default event loop, set a new one by @encukou in https://github.com/kwarunek/aiounittest/pull/22
    • Fixed deps for travis-ci py3.7

    New Contributors

    • @hroncok made their first contribution in https://github.com/kwarunek/aiounittest/pull/21
    • @encukou made their first contribution in https://github.com/kwarunek/aiounittest/pull/22

    Full Changelog: https://github.com/kwarunek/aiounittest/compare/1.4.1...1.4.2

    Source code(tar.gz)
    Source code(zip)
  • 1.4.1(Oct 22, 2021)

    What's Changed

    • Fix typo in documentation by @svisser in https://github.com/kwarunek/aiounittest/pull/17
    • Fix main example by @Zeskbest in https://github.com/kwarunek/aiounittest/pull/18
    • Re-export top-level imports to satisfy Mypy by @reivilibre in https://github.com/kwarunek/aiounittest/pull/19

    New Contributors

    • @svisser made their first contribution in https://github.com/kwarunek/aiounittest/pull/17
    • @Zeskbest made their first contribution in https://github.com/kwarunek/aiounittest/pull/18
    • @reivilibre made their first contribution in https://github.com/kwarunek/aiounittest/pull/19

    Full Changelog: https://github.com/kwarunek/aiounittest/compare/1.4.0...1.4.1

    Source code(tar.gz)
    Source code(zip)
a plugin for py.test that changes the default look and feel of py.test (e.g. progressbar, show tests that fail instantly)

pytest-sugar pytest-sugar is a plugin for pytest that shows failures and errors instantly and shows a progress bar. Requirements You will need the fol

Teemu 963 Dec 28, 2022
Ab testing - The using AB test to test of difference of conversion rate

Facebook recently introduced a new type of offer that is an alternative to the current type of bidding called maximum bidding he introduced average bidding.

null 5 Nov 21, 2022
Asyncio http mocking. Similar to the responses library used for 'requests'

aresponses an asyncio testing server for mocking external services Features Fast mocks using actual network connections allows mocking some types of n

null 93 Nov 16, 2022
Pytest support for asyncio.

pytest-asyncio: pytest support for asyncio pytest-asyncio is an Apache2 licensed library, written in Python, for testing asyncio code with pytest. asy

pytest-dev 1.1k Jan 2, 2023
Based on the selenium automatic test framework of python, the program crawls the score information of the educational administration system of a unive

whpu_spider 该程序基于python的selenium自动化测试框架,对某高校的教务系统的成绩信息实时爬取,在检测到成绩更新之后,会通过电子邮件的方式,将更新的成绩以文本的方式发送给用户,可以使得用户在不必手动登录教务系统网站时,实时获取成绩更新的信息。 该程序仅供学习交流,不可用于恶意攻

null 1 Dec 30, 2021
This is a web test framework based on python+selenium

Basic thoughts for this framework There should have a BasePage.py to be the parent page and all the page object should inherit this class BasePage.py

Cactus 2 Mar 9, 2022
py.test fixture for benchmarking code

Overview docs tests package A pytest fixture for benchmarking code. It will group the tests into rounds that are calibrated to the chosen timer. See c

Ionel Cristian Mărieș 1k Jan 3, 2023
A pytest plugin, that enables you to test your code that relies on a running PostgreSQL Database

This is a pytest plugin, that enables you to test your code that relies on a running PostgreSQL Database. It allows you to specify fixtures for PostgreSQL process and client.

Clearcode 252 Dec 21, 2022
A pytest plugin that enables you to test your code that relies on a running Elasticsearch search engine

pytest-elasticsearch What is this? This is a pytest plugin that enables you to test your code that relies on a running Elasticsearch search engine. It

Clearcode 65 Nov 10, 2022
This is a pytest plugin, that enables you to test your code that relies on a running MongoDB database

This is a pytest plugin, that enables you to test your code that relies on a running MongoDB database. It allows you to specify fixtures for MongoDB process and client.

Clearcode 19 Oct 21, 2022
Pytest-typechecker - Pytest plugin to test how type checkers respond to code

pytest-typechecker this is a plugin for pytest that allows you to create tests t

vivax 2 Aug 20, 2022
Green is a clean, colorful, fast python test runner.

Green -- A clean, colorful, fast python test runner. Features Clean - Low redundancy in output. Result statistics for each test is vertically aligned.

Nathan Stocks 756 Dec 22, 2022
splinter - python test framework for web applications

splinter - python tool for testing web applications splinter is an open source tool for testing web applications using Python. It lets you automate br

Cobra Team 2.6k Dec 27, 2022
A test fixtures replacement for Python

factory_boy factory_boy is a fixtures replacement based on thoughtbot's factory_bot. As a fixtures replacement tool, it aims to replace static, hard t

FactoryBoy project 3k Jan 5, 2023
A test fixtures replacement for Python

factory_boy factory_boy is a fixtures replacement based on thoughtbot's factory_bot. As a fixtures replacement tool, it aims to replace static, hard t

FactoryBoy project 2.4k Feb 5, 2021
splinter - python test framework for web applications

splinter - python tool for testing web applications splinter is an open source tool for testing web applications using Python. It lets you automate br

Cobra Team 2.3k Feb 5, 2021
Parameterized testing with any Python test framework

Parameterized testing with any Python test framework Parameterized testing in Python sucks. parameterized fixes that. For everything. Parameterized te

David Wolever 714 Dec 21, 2022
A test fixtures replacement for Python

factory_boy factory_boy is a fixtures replacement based on thoughtbot's factory_bot. As a fixtures replacement tool, it aims to replace static, hard t

FactoryBoy project 2.4k Feb 8, 2021