Last active
September 30, 2018 21:22
-
-
Save agronholm/efe7f674d038626d5dfff45388038655 to your computer and use it in GitHub Desktop.
Async pytest plugin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from functools import partial | |
| from inspect import iscoroutinefunction | |
| import pytest | |
| import hyperio | |
| try: | |
| from async_generator import isasyncgenfunction | |
| except ImportError: | |
| from inspect import isasyncgenfunction | |
| @pytest.hookimpl(hookwrapper=True) | |
| def pytest_fixture_setup(fixturedef, request): | |
| def wrapper(*args, **kwargs): | |
| backend = kwargs['hyperio_backend'] | |
| if strip_backend: | |
| del kwargs['hyperio_backend'] | |
| if isasyncgenfunction(func): | |
| gen = func(*args, **kwargs) | |
| try: | |
| value = hyperio.run(gen.__anext__, backend=backend) | |
| except StopAsyncIteration: | |
| raise RuntimeError('Async generator did not yield') | |
| yield value | |
| try: | |
| hyperio.run(gen.__anext__, backend=backend) | |
| except StopAsyncIteration: | |
| pass | |
| else: | |
| hyperio.run(gen.aclose) | |
| raise RuntimeError('Async generator fixture did not stop') | |
| else: | |
| yield hyperio.run(partial(func, *args, **kwargs), backend=backend) | |
| func = fixturedef.func | |
| if hasattr(func, '__wrapped__'): | |
| func = func.__wrapped__ | |
| if isasyncgenfunction(func) or iscoroutinefunction(func): | |
| strip_backend = False | |
| if 'hyperio_backend' not in fixturedef.argnames: | |
| fixturedef.argnames += ('hyperio_backend',) | |
| strip_backend = True | |
| fixturedef.func = wrapper | |
| yield | |
| def pytest_generate_tests(metafunc): | |
| if metafunc.definition.get_closest_marker('hyperio'): | |
| metafunc.fixturenames.append('hyperio_backend') | |
| # If an explicit hyperio_backend was defined, skip parametrization | |
| for marker in metafunc.definition.iter_markers(name='parametrize'): | |
| if 'hyperio_backend' in marker.args: | |
| return | |
| metafunc.parametrize('hyperio_backend', ['asyncio', 'curio', 'trio'], scope='session') | |
| @pytest.mark.tryfirst | |
| def pytest_pyfunc_call(pyfuncitem): | |
| if pyfuncitem.get_closest_marker('hyperio'): | |
| funcargs = pyfuncitem.funcargs | |
| backend = funcargs.get('hyperio_backend', 'asyncio') | |
| testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames} | |
| hyperio.run(partial(pyfuncitem.obj, **testargs), backend=backend) | |
| return True |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import pytest | |
| from async_generator import async_generator, yield_ | |
| from hyperio import sleep | |
| @pytest.fixture | |
| async def async_fixture(): | |
| await sleep(0) | |
| return 'foo' | |
| @pytest.fixture | |
| @async_generator | |
| async def asyncgen_fixture(): | |
| await sleep(0) | |
| await yield_('foo') | |
| await sleep(0) | |
| @pytest.mark.hyperio | |
| async def test_fixture(async_fixture): | |
| assert async_fixture == 'foo' | |
| @pytest.mark.hyperio | |
| async def test_asyncgen_fixture(asyncgen_fixture): | |
| assert asyncgen_fixture == 'foo' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment