diff --git a/README.rst b/README.rst index c63f72d2..9d2257a5 100644 --- a/README.rst +++ b/README.rst @@ -256,6 +256,10 @@ or an async framework such as `asynctest `_ + 0.17.0 (22-01-13) ~~~~~~~~~~~~~~~~~~~ - `pytest-asyncio` no longer alters existing event loop policies. `#168 `_, `#188 `_ diff --git a/pytest_asyncio/plugin.py b/pytest_asyncio/plugin.py index 4f5a0591..04b5e139 100644 --- a/pytest_asyncio/plugin.py +++ b/pytest_asyncio/plugin.py @@ -115,7 +115,13 @@ def pytest_configure(config): @pytest.mark.tryfirst def pytest_pycollect_makeitem(collector, name, obj): """A pytest hook to collect asyncio coroutines.""" - if collector.funcnamefilter(name) and _is_coroutine(obj): + if not collector.funcnamefilter(name): + return + if ( + _is_coroutine(obj) + or _is_hypothesis_test(obj) + and _hypothesis_test_wraps_coroutine(obj) + ): item = pytest.Function.from_parent(collector, name=name) if "asyncio" in item.keywords: return list(collector._genfunctions(name, obj)) @@ -128,6 +134,10 @@ def pytest_pycollect_makeitem(collector, name, obj): return ret +def _hypothesis_test_wraps_coroutine(function): + return _is_coroutine(function.hypothesis.inner_test) + + class FixtureStripper: """Include additional Fixture, and then strip them""" diff --git a/tests/hypothesis/test_base.py b/tests/hypothesis/test_base.py index e9273d0e..fbee75bf 100644 --- a/tests/hypothesis/test_base.py +++ b/tests/hypothesis/test_base.py @@ -2,6 +2,7 @@ sync shim for Hypothesis. """ import asyncio +from textwrap import dedent import pytest from hypothesis import given, strategies as st @@ -40,3 +41,48 @@ async def test_can_use_fixture_provided_event_loop(event_loop, n): semaphore = asyncio.Semaphore(value=0) event_loop.call_soon(semaphore.release) await semaphore.acquire() + + +def test_async_auto_marked(pytester): + pytester.makepyfile( + dedent( + """\ + import asyncio + import pytest + from hypothesis import given + import hypothesis.strategies as st + + pytest_plugins = 'pytest_asyncio' + + @given(n=st.integers()) + async def test_hypothesis(n: int): + assert isinstance(n, int) + """ + ) + ) + result = pytester.runpytest("--asyncio-mode=auto") + result.assert_outcomes(passed=1) + + +def test_sync_not_auto_marked(pytester): + """Assert that synchronous Hypothesis functions are not marked with asyncio""" + pytester.makepyfile( + dedent( + """\ + import asyncio + import pytest + from hypothesis import given + import hypothesis.strategies as st + + pytest_plugins = 'pytest_asyncio' + + @given(n=st.integers()) + def test_hypothesis(request, n: int): + markers = [marker.name for marker in request.node.own_markers] + assert "asyncio" not in markers + assert isinstance(n, int) + """ + ) + ) + result = pytester.runpytest("--asyncio-mode=auto") + result.assert_outcomes(passed=1)