8
votes

I am trying to write tests for aiohttp application. I am using pytest-aiohttp plugin. My intention is to initialize and run the application once before first test execution and tear down after all tests finished. pytest-aiohttp fixtures like 'loop', 'test_client' are very helpful but they have scope='function' which means I can not use them from my own fixture with scope='session'. Is there a way to workaround this? And if not then what would be a proper approach for achieving my goal without using built-in fixtures? My code is as follows (conftest.py)

@pytest.fixture()
def client(test_client, loop):
    app = init(loop)
    return loop.run_until_complete(test_client(app))

My tests then use this

class TestGetAlerts:
async def test_get_login_url(self, client):
    resp = await client.get('/api/get_login_url')
    assert resp.status == 200

So my fixture 'client' runs for every test, which is what i want to avoid

1

1 Answers

4
votes

test_client fixture is a simple wrapper around TestServer and TestClient classes from aiohttp.test_utils.

You can craft your own version of the fixture with 'session' scope.

But this way has own problems: tests should be isolated, in practice it means event loop recreation for every test.

But session-level aiohttp application doesn't support such loop recreation. Thus the app should be run in separate thread which makes writing test assertions much harder.

In my practice aiohttp application starts instantly but things like DB schema migration and DB fixtures applying takes time. These activities could be implemented in session scope easy as separate fixtures but app starting/stopping should be performed inside every test.