# Python Testing Pytest Asyncio

> Conventions for tests in echo-sdk — pytest + pytest-asyncio, async fixtures, dotenv loading, mocking provider SDKs. Use when adding or modifying tests under tests/. Use when this capability is needed.

- Skill: `tomevault-io/python-testing-pytest-asyncio` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/python-testing-pytest-asyncio`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/python-testing-pytest-asyncio/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/python-testing-pytest-asyncio

---


# Testing

Stack: `pytest`, `pytest-asyncio`, `python-dotenv`. Setup lives in `tests/conftest.py`.

## Rules

- **Mark async tests** with `@pytest.mark.asyncio` (or set the asyncio mode in conftest if it's already configured — check there first).
- **Async fixtures**: `@pytest.fixture` + `async def` returning the value, or `@pytest_asyncio.fixture` for explicit async fixtures.
- **Don't hit real providers in CI.** Mock provider SDKs (`unittest.mock.patch`, or pass an injected client to the constructor).
- **`.env` loaded in `conftest.py`**; tests assume env is available, but secrets should not be required for unit tests — use mocks.
- **Test the agentic loop end-to-end** when touching providers — `invoke()` with a tool that returns deterministically, assert the final context has the expected `ToolCall` + `ToolResult` + assistant message.
- **Test schemas with `model_validate`**, not by constructing fields manually — catches Pydantic v2 regressions.
- **Async resource cleanup in tests**: use `async with` or `try/finally` so a failing test doesn't leak subprocesses (MCP stdio especially).

## Existing patterns

- `tests/test_llm_response.py` — provider response shape.
- `tests/test_prompts.py` — prompt provider behavior.
- `tests/test_postgres_binder.py` — binder type mapping.

## Common mistakes

- Forgetting `@pytest.mark.asyncio` → test silently doesn't await.
- Hitting `bedrock.client(...)` in CI → mock it.
- Leaving MCP stdio managers open after a test → flakes from subprocess leaks.
- Asserting on full LLM response strings → brittle; assert on structure (tool calls, message roles).

## See also

- `[[python-async-discipline]]`, `[[echo-sdk-llm]]`

---
> Source: [eka-care/echo-sdk](https://github.com/eka-care/echo-sdk) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-06-16 -->

