generated from john/python-template
Begin implementation of Step 1. Implementation interrupted when I ran out of credits at openrouter. Credits added. Now trying to figure out how to restart the process...
This commit is contained in:
+32
-4
@@ -70,6 +70,14 @@ dev = [
|
||||
"pytest>=8.0",
|
||||
"pytest-asyncio>=0.25",
|
||||
]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
addopts = "--strict-markers -q"
|
||||
markers = [
|
||||
"unit: pure logic tests with no external dependencies",
|
||||
"integration: tests that touch framework or database contracts",
|
||||
"external: tests that call external services (slow, requires credentials)",
|
||||
]
|
||||
```
|
||||
|
||||
Key additions:
|
||||
@@ -77,6 +85,7 @@ Key additions:
|
||||
- **`pydantic-settings`** — for `BaseSettings` with env-var loading (this was split out of `pydantic` core in v2)
|
||||
- **`sqlmodel`** — provides SQLModel (which bundles SQLAlchemy + Pydantic model integration) and the SQLite driver
|
||||
- **`pytest` + `pytest-asyncio`** — in `dev` extras for test execution
|
||||
- **`[tool.pytest.ini_options]`** — strict marker checking enabled from the start; markers registered upfront per pytesting skill conventions
|
||||
|
||||
### Delete `hello.py`
|
||||
|
||||
@@ -452,20 +461,24 @@ isolated, fast, and leave no artifacts on disk.
|
||||
|
||||
import pytest
|
||||
from sqlmodel import Session, SQLModel, create_engine
|
||||
from sqlmodel.pool import StaticPool
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def session():
|
||||
"""Provide a clean database session for each test."""
|
||||
engine = create_engine(
|
||||
"sqlite://", # in-memory
|
||||
"sqlite://",
|
||||
connect_args={"check_same_thread": False},
|
||||
poolclass=StaticPool,
|
||||
)
|
||||
SQLModel.metadata.create_all(engine)
|
||||
with Session(engine) as session:
|
||||
yield session
|
||||
```
|
||||
|
||||
`StaticPool` ensures a single in-memory SQLite connection is shared across threads, which is required when `TestClient` (Step 5) spawns threads that would otherwise get separate in-memory databases. Establishing it now keeps the fixture stable across all future steps.
|
||||
|
||||
### `tests/test_config.py` — Configuration Hierarchy
|
||||
|
||||
| Class | Method | What It Verifies |
|
||||
@@ -503,8 +516,20 @@ def session():
|
||||
|
||||
### Marker Strategy (Step 1)
|
||||
|
||||
- Keep all Step 1 tests as default unit-level tests (no custom marker needed yet).
|
||||
- When slower integration or external tests are introduced, add explicit markers (for example `integration`, `external`) and keep names unchanged.
|
||||
- Markers (`unit`, `integration`, `external`) are registered upfront in `pyproject.toml` with `--strict-markers` enabled, per pytesting skill conventions.
|
||||
- All Step 1 tests are unmarked — they run in the default lane since they are fast, deterministic, and have no external dependencies.
|
||||
- When slower integration or external tests are introduced in later steps, apply explicit markers and keep test names unchanged.
|
||||
|
||||
### Test Workflow
|
||||
|
||||
Follow the two-phase approach from `resource://catalog/prompts/pytest-scaffold` and `resource://catalog/prompts/pytest-fill-scaffold`:
|
||||
|
||||
1. **Scaffold phase**: Create test files with class hierarchy, method names, and one-line docstrings only. Validate collection:
|
||||
- `uv run pytest --collect-only -q`
|
||||
2. **Fill phase**: Implement assertions, fixtures, and minimal test data. Treat scaffolded names and docstrings as locked. Validate execution:
|
||||
- `uv run pytest -q`
|
||||
|
||||
Scaffolded structure is treated as a stable baseline — do not rename, move, merge, split, or re-nest tests once the scaffold is reviewed.
|
||||
|
||||
---
|
||||
|
||||
@@ -521,11 +546,14 @@ When all of the following are true, Step 1 is done and Step 2 can begin:
|
||||
| 5 | `JobStatus` enum has exactly four values: `queued`, `processing`, `transcribed`, `failed` | `test_models.py` passes |
|
||||
| 6 | Foreign key relationships work: Document→Job→Transcript | `test_models.py` passes |
|
||||
| 7 | `create_all()` bootstraps the schema; `get_session()` yields a working session | `test_db.py` passes |
|
||||
| 8 | All tests pass: `uv run pytest tests/` | CI / local run |
|
||||
| 8 | All tests pass: `uv run pytest -q` | CI / local run |
|
||||
| 9 | `hello.py` is deleted | File inspection |
|
||||
| 10 | `pyproject.toml` includes `openrouter`, `sqlmodel`, `pydantic-settings`, `pytest`, `pytest-asyncio` | File inspection |
|
||||
| 10a | `pyproject.toml` has `[tool.pytest.ini_options]` with `--strict-markers` and registered markers | File inspection |
|
||||
| 11 | `.env.example` documents all config vars; `.env` is in `.gitignore` | File inspection |
|
||||
| 12 | `setup_logging()` uses `logging.config.dictConfig` with centralized formatter/handler/root config | File inspection |
|
||||
| 13 | `uv run pytest --collect-only -q` shows expected test hierarchy | Local run |
|
||||
| 14 | `uv run pytest -q` passes all tests | Local run |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user