# Test coverage map

> **Audience:** the maintainer and any contributor.
> **What this is:** the canonical reference for what `mgf-common`
> tests at each layer of the test pyramid (rules **TS-19** /
> **TS-20** / **TS-21** in [`TESTING.md`](../standards/TESTING.md)).
> Updated each release that touches the test surface.

This doc is a **template + roadmap**:

- **As a template:** consumer projects reading
  [`docs/standards/TESTING.md`](../standards/TESTING.md) §13 see
  the rules; this doc shows how `mgf-common` itself implements
  them. Copy the shape for your project's `docs/internal/TEST_COVERAGE.md`.
- **As a roadmap:** the per-module breakdown surfaces
  coverage gaps — modules with only unit tests but no
  integration/e2e — that next polish rounds can address.

---

## Layer summary (as of v0.24.0)

| Layer | Directory | Marker | Count | Total runtime |
|---|---|---|--:|---|
| smoke | `tests/smoke/` | `@pytest.mark.smoke` | 7 | < 100 ms |
| unit | `tests/unit/` (mirrors `src/`) | (default) | 1312 | ~ 12 s |
| public-surface contract | `tests/public_surface/` | (default — sub-tier of unit) | 113 | ~ 2 s |
| integration | `tests/integration/` | `@pytest.mark.integration` | 5 | < 1 s |
| e2e | `tests/e2e/` | `@pytest.mark.e2e` | 8 | < 1 s |
| **total** | | | **1445** | ~ 16 s |

Run a layer in isolation:

```bash
pytest -m smoke              # 7 tests, <100 ms
pytest -m e2e                # 8 tests, <1s
pytest -m integration        # 5 tests, <1s
pytest tests/unit            # the unit base
pytest                       # everything
```

---

## Per-module coverage

Maps each `mgf.common.<module>` to the test layers that cover
it. Gaps (modules with only unit coverage) are intentional
follow-up candidates — they're not bugs, but they're places
where a future round could harden the contract.

| Module | Unit | Integration | E2E | Smoke |
|---|:-:|:-:|:-:|:-:|
| `mgf.common` (lifecycle/identity) | ✅ 27 | — | — | — |
| `mgf.common.exceptions` | ✅ 30+ | — | — | ✅ 1 |
| `mgf.common.config` | ✅ 30+ | — | — | — |
| `mgf.common.observability` | ✅ ~120 (logging, OTel, redaction, crash) | — | ✅ 5 (via process redaction E2E) | — |
| `mgf.common.settings` | ✅ ~30 | — | — | — |
| `mgf.common.progress` (incl. asyncio) | ✅ ~30 | — | — | — |
| `mgf.common.vault` | ✅ ~25 | — | — | — |
| `mgf.common.versioned` | ✅ ~10 | — | — | — |
| `mgf.common.cli` | ✅ ~50 | — | — | — |
| `mgf.common.pytest_plugin` | ✅ ~15 | — | — | — |
| `mgf.common.registry` | ✅ ~10 | — | — | — |
| `mgf.common.http` | ✅ ~10 | — | — | — |
| `mgf.common.fastapi` | ✅ ~25 (incl. exception middleware, request id) | — | — | — |
| `mgf.common.db` | ✅ ~15 | — | — | — |
| `mgf.common.alembic` | ✅ 16 | — | — | — |
| `mgf.common.django` | ✅ ~10 | — | — | — |
| `mgf.common.providers` | ✅ ~5 | — | — | — |
| **`mgf.common.process`** | **✅ 84** | **✅ 5** | **✅ 8** | **✅ 7** |

**Process is the reference implementation** of the four-layer
pyramid. It got that way through three polish rounds (v0.21 →
v0.22 → v0.23) — the test pyramid was filled out across releases
as the surface stabilised. The pattern: **once unit tests prove
a feature's surface, the next round adds the higher layers
that pin real-consumer contracts.**

---

## Coverage gaps (planned future polish)

The modules below have only unit coverage today. Each is a
candidate for a future polish round that adds integration / e2e
layers. Not blockers — unit tests alone are conformance-passing
for a stable module — but these are the places where end-to-end
contract pinning would catch the most real failures.

| Module | What integration/e2e would catch | Priority |
|---|---|---|
| `mgf.common.observability` (full bootstrap chain) | LOG-01 / LOG-02 cloud-native shape regressions; redaction-vs-formatter wire shape | high (load-bearing for every consumer) |
| `mgf.common.fastapi` (middleware composition) | RequestId + ExceptionTranslation interaction with real HTTP request flow; HTTP-01 hierarchy end-to-end | medium (FastAPI-only consumers) |
| `mgf.common.db` + `alembic` | configure_env round-trip with a real SQLite file; PAPER-22 include_object filter against PostGIS-shaped schema | medium |
| `mgf.common.cli` (catch-up) | The `mgf-common doctor` flow against a synthetic project tree | low (already exercised by VManager's catch-up workflow) |
| `mgf.common.django` (AppConfig + bootstrap) | BOOTSTRAP-01 setup_logging=False in a synthetic Django project | medium (would close inthewords' contract surface) |

---

## Adding a new test — decision tree

Per [`TESTING.md`](../standards/TESTING.md) §13.9:

```
Single function/class/module                    → unit/
Two-or-more modules composed (no real bootstrap) → integration/
Requires real mgf.common.bootstrap()             → e2e/
"Wheel imports + happy path"                     → smoke/
> 1 second runtime                               → add @pytest.mark.slow
Hits real external system (Sentry, Slack, …)    → §12 pattern
```

When in doubt, prefer the lower layer. A test that's faster +
more isolated is a better contract pin than the same logic
spread across a slower test.

---

## Process for updating this doc

Maintainer process — update this doc when:

- A new module is added to `src/mgf/`.
- A test layer count changes by ≥10 (e.g., a polish round
  adds a new e2e suite for a module).
- A coverage gap closes (mark the module ✅ in the gaps table
  and remove from the gaps list).

The numbers in the layer summary are mechanically verifiable:

```bash
for layer in unit smoke integration e2e public_surface; do
    cnt=$(python -m pytest "tests/$layer/" --co -q 2>&1 | grep -oP "\d+(?= tests collected)")
    echo "$layer $cnt"
done
```

A future iteration may auto-generate this table from the live
counts; for now it's manually maintained.

---

## Cross-references

- [`docs/standards/TESTING.md`](../standards/TESTING.md) — the
  rules (TS-01..TS-21).
- [`docs/standards/TESTING.md`](../standards/TESTING.md) §13 —
  the layer-markers operational pattern (TS-19, TS-20, TS-21).
- [`docs/cutover/v0.23.0.md`](../cutover/v0.23.0.md) — the
  release that introduced the four-layer process tests.
- [`docs/cutover/v0.24.0.md`](../cutover/v0.24.0.md) — the
  release that codified the pattern as the standard.
