Testing And TDD
The repo expects tests before or alongside behavior changes. Use the smallest test level that proves the behavior: service-level tests for business logic, route-level tests for HTTP behavior, contract tests for stable public surfaces, and integration tests only when the database or stack boundary is the thing being proven.
Canonical Commands
make pytest
make lint
make typecheck
make pytest-cov
make testDo not run pytest directly. make pytest is the canonical command for this repo.
Test Layout
packages/python-server-quickstart/tests/
contracts/ # package and API contract tests
domains/ # domain behavior
middleware/ # API key, JWT, rate limit, envelope, origin checks
seeds/ # seed validation
test_*.py # core package and integration behaviorMocking Rules
| Integration | Test posture |
|---|---|
| Stripe | Mock with respx or service doubles |
| Mailgun | Mock HTTP or service boundary |
| Blockchain RPCs | Mock chain verification inputs and clients |
| DB sessions | Use async fixtures or AsyncMock where a real DB is not required |
Example Test Shape
import pytest
@pytest.mark.asyncio
async def test_service_rejects_missing_application() -> None:
result = await service_method(application=None)
assert result.status == "rejected"Common Mistakes
- Writing a broad integration test when a service-level test would isolate the branch.
- Hitting the network in tests.
- Forgetting
@pytest.mark.asyncioon async tests. - Skipping docs and
docs/manifest.jsonwhen changing endpoints.