Development guidelines¶
- Trunk‑based; squash merges
- Small PRs; tests + docs required
- Code style: ruff + black; mypy strict
- Perf‑sensitive changes include benchmarks
Project setup¶
Prerequisites¶
- Python: 3.9 or higher
- git: For version control
One-time setup¶
-
Clone the repository
git clone https://github.com/ankan97dutta/profilis.git cd profilis -
Create and activate a virtual environment
python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate -
Install the package in editable mode with dev dependencies
This installs the library plus pytest, pytest-cov, pytest-asyncio, mypy, ruff, black, pre-commit, and uvicorn.pip install -e ".[dev]" -
Install pre-commit hooks (recommended)
Hooks run ruff (lint + format), mypy, and basic file checks on commit.pre-commit install -
Verify setup
pytest -q mypy src/ tests/ examples/
Quick reference¶
| Task | Command |
|---|---|
| Run all tests | pytest |
| Verbose tests | pytest -v |
| Tests + coverage | pytest --cov=profilis --cov-report=term-missing |
| Single test file | pytest tests/test_fastapi_ui.py |
| Tests by keyword | pytest -k "test_metrics" |
| Lint | ruff check src/ tests/ |
| Format | ruff format . or black . |
| Type-check | mypy src/ tests/ examples/ |
Test-driven development (TDD)¶
We use test-first development so that design is driven by behaviour and changes stay safe.
The TDD cycle¶
- Red — Write a failing test that defines the desired behaviour (e.g. a new function, edge case, or fix). Run
pytestand confirm the test fails for the right reason. - Green — Write the smallest amount of code that makes the test pass. Avoid adding behaviour the test doesn’t ask for.
- Refactor — Improve names, structure, and performance while keeping all tests green. Re-run the suite after refactors.
Repeat this cycle in small steps so you always have a clear, failing test before writing production code.
Running tests as you work¶
- Full suite:
pytestorpytest -q - Current file:
pytest path/to/test_file.py - Single test:
pytest path/to/test_file.py::test_function_name - By pattern:
pytest -k "adapter or middleware"
Run tests often (e.g. after each Red/Green/Refactor step) so feedback is fast.
Test layout¶
- Tests live under
tests/. - Mirror the source layout where it helps: e.g.
tests/test_fastapi_ui.pyfor FastAPI UI,tests/test_asgi_middleware.pyfor ASGI middleware. - Use pytest fixtures for shared setup (collectors, emitters, app instances). See existing tests for patterns.
- Async tests: use
async def test_...; pytest-asyncio is enabled inpyproject.toml(asyncio_mode = "auto").
What to test¶
- New behaviour: Add tests that describe the public behaviour (inputs, outputs, side effects). Prefer testing through the public API.
- Bug fixes: Add a test that fails with the bug and passes after the fix (regression test).
- Refactors: Keep or adjust existing tests so they still pass; add tests only if you’re also changing behaviour.
Example TDD flow¶
- You want a helper that normalises route paths. Red: add
tests/test_utils.pywithdef test_normalise_route_strips_trailing_slash(): ...and runpytest tests/test_utils.py— it fails (e.g. missing module or assertion). - Green: Implement the helper in
src/profilis/...and import it in the test; runpytestuntil the test passes. - Refactor: Rename or simplify the implementation; run
pytestagain to confirm nothing breaks.
Code quality¶
- Linting:
ruff check src/ tests/(and fix or acknowledge any issues). - Formatting:
ruff format .orblack .before committing. - Types:
mypy src/ tests/ examples/must pass (seepyproject.tomlfor config). - Pre-commit: With
pre-commit install, these run automatically ongit commit. Runpre-commit run --all-filesmanually if needed.
Pull requests¶
- Branch: Use a short-lived branch from main (
feat/...,fix/...,perf/...,chore/...). - Scope: Prefer small, focused PRs.
- Requirements: All tests pass; ruff and mypy pass; new behaviour or fixes have tests; user-facing changes have doc updates.
- Commits: Follow Conventional Commits (e.g.
feat(adapters): add route exclusion for Sanic).
Related¶
- Contributing — How to contribute and what we expect
- Architecture — System design and components