7

I use aiohttp, pytest and pytest-cov to get coverage of my code. I want to get better coverage< but now I am a little bit stuck, because event simple code does not show 100% cov. For example this piece of code:

@session_decorator()
async def healthcheck(session, request):
    await session.scalar("select pg_is_in_recovery();")
    return web.json_response({"status": "ok"})

in coverage report it shows that line with return is not covered.

I have read this link Code coverage for async methods. But this is for C# and I can not understand:

This can happen most commonly if the operation you're awaiting is completed before it's awaited.

My code to run tests:

python3.9 -m pytest -vv --cov --cov-report xml --cov-report term-missing

My test for code above

async def test_healthz_page(test_client):
    response = await test_client.get("/healthz")
    assert response.status == HTTPStatus.OK
Anton Pomieshchenko
  • 2,051
  • 2
  • 10
  • 24
  • How did your unittest invoke the `healthcheck` function? You may need to adapt your test case methods such that they execute as intended, please take a look at [this thread](https://stackoverflow.com/questions/23033939/how-to-test-python-3-4-asyncio-code) on how this may be done. – metatoaster Aug 18 '21 at 05:24
  • added in the post – Anton Pomieshchenko Aug 18 '21 at 05:33
  • You will need to mark your test correctly with pytest, see [thread](https://stackoverflow.com/questions/49936724/async-fixtures-with-pytest) and [thread](https://stackoverflow.com/questions/45944158/python-pytest-cases-for-async-and-await-method) and [thread](https://stackoverflow.com/questions/65652242/testing-asyncio-with-pytest-how-to-test-a-try-except-block-by-mocking-the-event) for examples. – metatoaster Aug 18 '21 at 05:54
  • Pytest doesn't have built-in support for async tests. What plugin do you use for that, `pytest-asyncio` or something else? – hoefling Aug 18 '21 at 06:09
  • ``` platform darwin -- Python 3.9.2, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 cachedir: .pytest_cache rootdir: configfile: pytest.ini, testpaths: tests plugins: Faker-8.9.1, cov-2.12.1, env-0.6.2, anyio-3.2.1, aiohttp-0.3.0 collected 53 items ``` – Anton Pomieshchenko Aug 18 '21 at 06:55
  • Tried to install pytest-asyncio it does not work at all) so it seems some plugin and this functionality. I mean ability to run async tests. Maybe anyio? – Anton Pomieshchenko Aug 18 '21 at 06:56
  • Even with asyncio properly setup I have the same issue; the `return` like is never shown as covered even if it is. – bfontaine Apr 11 '23 at 14:37
  • 2
    To clarify: the code after the first `await` is never shown as covered. – bfontaine Apr 11 '23 at 14:45

1 Answers1

3

I had the same issue when testing FastAPI code using asyncio. The fix is to create or edit a .coveragerc at the root of your project with the following content:

[run]
concurrency = gevent

If you use a pyproject.toml you can also include this section in that file instead:

[tool.coverage.run]
concurrency = ["gevent"]

In addition, you have to pip install gevent. If using Poetry, run poetry add --group dev gevent.

If the above doesn’t work, try using concurrency = thread,gevent instead (see this comment. Note it says to use --concurrency but this option is not available when you use pytest-cov; you must use .coveragerc).

bfontaine
  • 18,169
  • 13
  • 73
  • 107