Treść z repozytorium z zachowaniem nagłówków, przykładów, kodu, tabel, linków i obrazów.
Python Testing Strategies — Quick Reference
Setup (CRITICAL)
Set asyncio_mode = "auto" in pyproject.toml to auto-detect async tests without markers. (The default "strict" mode also works if you mark tests with @pytest.mark.asyncio.)
See examples.md for the complete conftest.py and pyproject.toml setup.
Test Client
Use httpx.AsyncClient + ASGITransport — never TestClient for async tests.
See examples.md for client fixture setup.
Required Coverage Per Endpoint
- Happy path (create, read, update, delete)
- Not found (404)
- Validation error (422)
- Auth failure (401) — if protected
- Soft delete — deleted records not returned
Test Naming
async def test_create_item(): # Happy path
async def test_create_item_missing_name(): # Validation
async def test_get_item_not_found(): # 404
async def test_get_item_soft_deleted(): # Soft deleteTest Data Factories
Use simple factory functions with sensible defaults. Override only what the test cares about.
See examples.md for factory patterns.
Running Tests
pytest # All tests
pytest tests/test_items.py # One file
pytest -k "test_create" # By name pattern
pytest --tb=short -q # Quiet outputGotchas
- Missing `asyncio_mode = "auto"` silently breaks everything. Tests appear to pass (0 collected) or hang indefinitely. Add
[tool.pytest.ini_options] asyncio_mode = "auto"topyproject.tomlbefore writing any async test. This is the #1 cause of "my tests don't run."
- `TestClient` and `AsyncClient` are not interchangeable.
TestClient(from Starlette) is synchronous — it blocks.AsyncClient(from httpx) is async — it uses the event loop. If your app usesasync defroutes withawait, you must useAsyncClientwithASGITransport. UsingTestClientmay hide async bugs because it runs synchronously.
- Database state leaks between tests without proper cleanup. Each test needs a clean database. Use an
autouse=Truefixture that creates/drops tables, or truncate between tests. Without this, test order matters and random failures appear in CI.
- `response.json()` returns snake_case from FastAPI by default. If your Pydantic models use
alias_generator, the JSON keys may differ from your Python field names. Always assert against the actual JSON keys, not the Python attribute names.
- Forgetting to `await` in async tests gives confusing errors. If you see
<coroutine object ...>in test output instead of actual data, you forgot anawait. Everyclient.get(),client.post(), etc. must be awaited.

