Hello everyone,
first-time poster here.
I’m having some strange unexplainable behavior with pytest-cov
that uses coverage
underneath.
Some lines are falsely (most-likely) detected as uncovered (shows as hits="0"
in xml report)
Here is a FastAPI route endpoint with it’s test case:
# main.py
@router.get("/admin", summary="Admin Page")
async def devops_tools_admin(request: DCCRequest, db: AsyncSession = Depends(get_db_session), json: Optional[str] = None):
payload = {
"request": request,
"data": {
"bans": await get_banips(db),
"sessions": await crud.get_sessions(db),
"shortlinks": await crud.get_shortlinks(db)
}
}
return TemplateResponse(payload,name="admin/admin.html")
# test_main.py
async def test_admin_root(client: AsyncClient):
res = await client.get("/admin")
assert res.status_code == 200
assert "html" in res.headers.get("content-type")
In coverage report, all lines are covered instead of return
statement.
In other test cases that also return TemplateResponse
it shows as being covered.
In this particular case, I’ve attempted to return with empty payload, that is only necessary
return TemplateResponse({"request": request, "data": {}},name="admin/admin.html")
It’s still the same.
Another example would be this:
from fastapi import APIRouter, Depends, Request
from httpx import AsyncClient
from dccwebtool.app.database import AsyncSession, get_db_session
from dccwebtool.app.databases import auth as Auth
from dccwebtool.app.dependencies import get_token_cookie
from dccwebtool.app.library.responses import SuccessResponse
router = APIRouter(dependencies=[Depends(get_token_cookie)])
# main.py
@router.post("/admin/passwords/{action}")
async def admin_passwords_action_POST(
request: Request,
action: str,
db: AsyncSession = Depends(get_db_session),
):
if action == "editacl":
payload = await request.json()
payload["user_id"] = int(payload["user_id"])
try:
user = await Auth.get_user_by_id(payload["user_id"])
for old_acl in await user.awaitable_attrs.acl:
await Auth.remove_acl(db, old_acl)
for acl in payload["acls"]: # Shows as uncovered.
entry = Auth.AclCreate(page_url=acl["url"], page_name=acl["name"]) # Shows as uncovered.
await Auth.add_acl_for_user(db, entry, payload["user_id"]) # Shows as uncovered.
except Exception as e:
return SuccessResponse(False, f"Exception ({type(e).__name__}) occurred. Error: {e}", 500)
return SuccessResponse(acls=payload["acls"]) # Shows as uncovered.
# test_main.py
async def test_admin_passwords_editacl(client: AsyncClient):
entry = await Auth.get_user_by_name('normal_user')
kwargs = {
"url": "/admin/passwords/editacl",
"json": {
"user_id": entry.id,
"acls": [
{"url": "/links", "name": "Links"},
{"url": "/static-file-manager", "name": "Static File Manager"},
]
}
}
# Attempt to update ACL for `normal_user`.
res = await client.post(**kwargs)
assert res.status_code == 200
assert "json" in res.headers.get("content-type")
assert res.json()["acls"] == kwargs["json"]["acls"] # Test successfully passes
I’m running pytest like this:
pytest --cov --cov-report=xml
with following configuration in pyproject.toml
[tool.pytest.ini_options]
addopts = "-x"
asyncio_default_fixture_loop_scope = "session"
asyncio_mode = "auto"
filterwarnings = []
pythonpath = [ '.' ]
Can anyone help?