Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a warning when setting up async fixtures #10839

Open
seifertm opened this issue Mar 26, 2023 · 1 comment
Open

Add a warning when setting up async fixtures #10839

seifertm opened this issue Mar 26, 2023 · 1 comment
Labels
topic: fixtures anything involving fixtures directly or indirectly type: enhancement new feature or API change, should be merged into features branch

Comments

@seifertm
Copy link

What's the problem this feature will solve?

Pytest cannot evaluate fixture that are async functions or async generators. Users of async pytest plugins may unintentionally annotate those functions with @pytest.fixture rather than the async plugin's fixture function.

The fixture result ends up to be an unawaited async generator or coroutine, which is not what the user expected. Most of the time, the corresponding tests will fail. However, when the user defines an autouse fixture to perform setup or teardown, the fixture can silently fail.

Fixture results in async generator
import pytest

@pytest.fixture
async def async_fixture():
    yield 42

def test_this(async_fixture):
    assert async_fixture == 42  # fails
Fixture results in coroutine
import pytest

@pytest.fixture
async def async_fixture():
    return 42

def test_this(async_fixture):
    assert async_fixture == 42  # fails
Fixture silently does nothing
import pytest

@pytest.fixture(autouse=True)
async def async_fixture():
    yield 42
   # perform teardown

def test_this():
    assert True  # succeeds but should fail

Describe the solution you'd like

Pytest emits the following warning when running async test functions without an async plugin (see #2224):

PytestUnhandledCoroutineWarning: async def functions are not natively supported and have been skipped.
  You need to install a suitable plugin for your async framework, for example:
    - anyio
    - pytest-asyncio
    - pytest-tornasync
    - pytest-trio
    - pytest-twisted

The warning is emitted as part of a trylast hook to pytest_pyfunc_call. That means async pytest plugins can create hook wrappers to synchronize the test function and prevent the warning from being emitted.

I suggest to add the same behavior to the use of @pytest.fixture on async functions or async generators.

Examples

Alternative Solutions

#9962 proposes a mechanism to await results of awaitable tests and fixtures. It can potentially address the issue described here.

Additional context

From the above list of async plugins, only anyio, pytest-asyncio, and pytest-trio make use of pytest_fixture_setup.

@nicoddemus nicoddemus added type: enhancement new feature or API change, should be merged into features branch topic: fixtures anything involving fixtures directly or indirectly labels Mar 26, 2023
@seifertm
Copy link
Author

This approach may collide with anyio which uses the standard @pytest.fixture decorator for coroutines and async generators.

https://anyio.readthedocs.io/en/stable/testing.html#asynchronous-fixtures

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: fixtures anything involving fixtures directly or indirectly type: enhancement new feature or API change, should be merged into features branch
Projects
None yet
Development

No branches or pull requests

2 participants