pytest-trio
                                
                                
                                
                                    pytest-trio copied to clipboard
                            
                            
                            
                        Async fixtures don't support `pytest.mark.usefixtures()`
Async fixtures can't be used in @pytest.mark.usefixtures(...) decorators.
I'm sure this is a side-effect of the trio-fixture workaround approach explained in the docs, but it should be possible to examine the test function's marks and honor them.
I guess this has the same cause as #123 -- we're not properly querying pytest to figure out the list of fixtures. I would guess fixing one would also fix the other.
I just got bit by this too. Min viable reproduction, in case it's useful as a testcase somewhere (though probably not because of the added trio_asyncio dep):
import asyncio
import pytest
import trio
import trio_asyncio
@pytest.fixture
async def trio_asyncio_loop():
    # When a ^C happens, trio send a Cancelled exception to each running
    # coroutine. We must protect this one to avoid deadlock if it is cancelled
    # before another coroutine that uses trio-asyncio.
    with trio.CancelScope(shield=True):
        async with trio_asyncio.open_loop() as loop:
            yield loop
@pytest.mark.usefixtures('trio_asyncio_loop')
class TestMetatest:
    async def test_the_thing(self):
        await trio_asyncio.aio_as_trio(asyncio.sleep)(0)
For posterity / any wandering ~~googlers~~ travelers:
_____________________________________________________________________________________________________________________________ TestMetatest.test_the_thing ______________________________________________________________________________________________________________________________
self = <tests.unittests.datastores.test_postgres.TestMetatest object at 0x7fbd4be01af0>
    async def test_the_thing(self):
        from trio_asyncio import aio_as_trio
>       await aio_as_trio(asyncio.sleep)(0)
tests/unittests/datastores/test_postgres.py:21:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <trio_asyncio._adapter.Asyncio_Trio_Wrapper object at 0x7fbd4be319d0>, args = (0,), kwargs = {}, f = <coroutine object _call_defer at 0x7fbd4bd56c00>
    async def __call__(self, *args, **kwargs):
        if self.args:
            raise RuntimeError("Call 'aio_as_trio(proc)(*args)', not 'aio_as_trio(proc, *args)'")
        # We route this through _calL_defer because some wrappers require
        # running in asyncio context
        f = _call_defer(self.proc, *args, **kwargs)
>       return await self.loop.run_aio_coroutine(f)
E       AttributeError: 'NoneType' object has no attribute 'run_aio_coroutine'
The workaround is simple, though not DRY:
class TestMetatest:
    # Explicitly call for the fixture on every test case instead of using mark.usefixtures
    async def test_the_thing(self, trio_asyncio_loop):
        await trio_asyncio.aio_as_trio(asyncio.sleep)(0)