{"id":6203,"library":"pytest-trio","title":"Pytest Trio Plugin","description":"pytest-trio is a pytest plugin designed to facilitate testing projects that leverage Trio, a friendly library for concurrency and async I/O in Python. It enables writing asynchronous tests without boilerplate, provides useful Trio-specific fixtures like `nursery` and `autojump_clock`, and supports async fixtures. The current stable version is 0.8.0, and it follows a release cadence tied to Trio and pytest compatibility updates.","status":"active","version":"0.8.0","language":"en","source_language":"en","source_url":"https://github.com/python-trio/pytest-trio","tags":["pytest","trio","async","testing","plugin","concurrency"],"install":[{"cmd":"pip install pytest-trio","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core testing framework.","package":"pytest","version":">=7.2.0","optional":false},{"reason":"Asynchronous I/O framework.","package":"trio","version":">=0.22.0","optional":false},{"reason":"Used for handling results of coroutines and generators.","package":"outcome","version":">=1.1.0","optional":false}],"imports":[{"note":"Used to explicitly mark an async test function or fixture that uses Trio. Can be omitted if 'trio_mode = true' is set in pytest.ini.","symbol":"pytest.mark.trio","correct":"import pytest\n\n@pytest.mark.trio\nasync def test_something():\n    ..."},{"note":"Decorator to explicitly mark an async fixture as a Trio fixture, ensuring it runs within the Trio event loop.","symbol":"pytest_trio.trio_fixture","correct":"from pytest_trio import trio_fixture\n\n@trio_fixture\nasync def my_fixture():\n    ..."},{"note":"A built-in fixture provided by pytest-trio for managing background tasks.","symbol":"nursery","correct":"async def test_with_nursery(nursery):\n    await nursery.start(some_task)"},{"note":"A built-in fixture that provides a mock clock, useful for testing time-sensitive code without real-time delays.","symbol":"autojump_clock","correct":"async def test_with_clock(autojump_clock):\n    await trio.sleep(1)"}],"quickstart":{"code":"# pytest.ini\n[pytest]\ntrio_mode = true\n\n# test_example.py\nimport trio\n\nasync def test_sleep():\n    start_time = trio.current_time()\n    await trio.sleep(0.01) # Use a small sleep for quick tests\n    end_time = trio.current_time()\n    assert end_time - start_time >= 0.01\n\nasync def test_should_pass_with_fixture(nursery):\n    results = []\n    async def background_task():\n        await trio.sleep(0.001)\n        results.append('done')\n    nursery.start_soon(background_task)\n    await trio.sleep(0.002) # Ensure background task has time to run\n    assert 'done' in results\n\n# Run with: pytest test_example.py","lang":"python","description":"To quickly get started, create a `pytest.ini` file in your project root with `trio_mode = true`. This enables Trio support for all async tests. Then, write `async def` test functions. `pytest-trio` automatically provides useful fixtures like `nursery` for managing background tasks."},"warnings":[{"fix":"Wrap teardown logic in a `finally` block within your async fixtures to guarantee execution, e.g., `try: yield; finally: await cleanup()`.","message":"If a `yield` in an async fixture (decorated with `@pytest.fixture` or `@pytest_trio.trio_fixture`) is cancelled, it will raise `trio.Cancelled` and teardown code after the `yield` might not execute. This differs significantly from standard pytest fixtures where `yield` never raises an exception. Ensure critical cleanup is in a `finally` block.","severity":"breaking","affected_versions":">=0.6.0"},{"fix":"Ensure `trio` is updated to `0.22.0` or later. If catching exceptions, prefer `ExceptionGroup` over `MultiError`.","message":"Trio 0.22.0 deprecated `trio.MultiError` in favor of Python's standard `BaseExceptionGroup` (PEP 654). `pytest-trio` 0.8.0 has been updated to use `ExceptionGroup` exclusively, requiring `trio>=0.22.0`. Older versions of `pytest-trio` with newer `trio` might encounter deprecation warnings or compatibility issues.","severity":"breaking","affected_versions":"All versions, especially when paired with Trio <0.22.0 or trying to catch `MultiError`."},{"fix":"For projects exclusively using Trio, set `trio_mode = true` in `pytest.ini`. Otherwise, consistently use `@pytest.mark.trio` on all Trio-dependent tests and async fixtures.","message":"Without `trio_mode = true` in `pytest.ini`, `pytest-trio` only processes tests and fixtures explicitly marked with `@pytest.mark.trio` or `@pytest_trio.trio_fixture`. This can lead to async tests being skipped or not running correctly if not explicitly marked.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Design tests to be atomic and independent, relying on fixtures to provide isolated setup/teardown for each test run. Be mindful that global state managed outside of Trio fixtures might not persist across tests as expected.","message":"`pytest-trio` runs `trio.run()` for each individual test, creating a fresh Trio environment. This differs from how standard pytest fixtures might be set up once for multiple tests, and can occasionally surprise users expecting a single shared Trio event loop across a test module or class.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Upgrade to Python 3.7 or a newer supported version.","message":"Support for Python 3.5 and 3.6 was removed in older versions of `pytest-trio`. Current versions require Python 3.7 or newer.","severity":"breaking","affected_versions":"0.7.0 and later"},{"fix":"Monitor `pytest-trio`'s GitHub issues for updates or consider pinning `pytest` to a version prior to 8.4.2 if encountering this issue.","message":"There are reports that `pytest-trio` tests may fail with `pytest` 8.4 due to empty tracebacks when the plugin raises an exception directly. This indicates a potential compatibility issue with newer `pytest` versions.","severity":"gotcha","affected_versions":"`pytest-trio` 0.8.0 with `pytest` >= 8.4.2"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z","problems":[]}