Co-located Python tests: discovery-reconciliation guard, then the `_test.py` move (after #990) nf-58s5 ← Beads

closed priority 2 task unassigned

Twinned from https://github.com/cfsh/ninefold/issues/995 by tools/beads/import_github.py's reconcile pass.

Second of three chunks splitting the co-location programme (Aedan: "split into separate chunks, this will be a lot of context for poor devs"). Do this after #990 lands — it extends the python presubmit lane and follows the convention STYLE_GUIDE.md (created by #990) states. The probe chunk (#996) is unrelated to this one.

Aedan's ask, verbatim (the ask that started the convention, from #485):

> "i am not sure the style guide for where we're putting tests atm, e.g. tools/{nflib,tests}/{foo.py,foo_test.py}. I propose we always put tests next to the relevant file, no tests directory (test_data directories allowed). Do u concur? Also should we codify this in a ninefold/STYLE_GUIDE.md?"

Context

The convention (STYLE_GUIDE.md, from #990): Python tests are <subject>_test.py beside their subject; no tests/ directories; test_data/ allowed. Today ~15 test_*.py files sit in tools/tests/, discovered by presubmit.py:156-157 with unittest discover -s tools/tests -p "test_*.py".

Two measured silent-loss modes make the move dangerous without a guard (#494 §1.4 + reviewer F3 there; design 005 S14):

  1. unittest discover skips a directory with no __init__.py silently — measured reporting OK / Ran 1 test while a second test file sat unloaded beside it.
  2. A -p pattern matching nothing reports Ran 0 tests / OK / exit 0 — and test_*.py does not match *_test.py, so a half-flipped migration reads green.
Prescription

Two PRs, guard first (B7 — make the failure impossible before creating its opportunity):

  1. PR 1 — the discovery-reconciliation guard. In the python lane: count *_test.py + test_*.py files on disk under the discovery roots, count test modules unittest actually loaded, fail on mismatch (D2; same spirit as #782). Add __init__.py to every directory that will hold a _test.py (tools/nflib/ and tools/pr/ have them — verify; repo root discovery needs deciding by the dev). Unit-test the guard against a fixture tree with a package-less dir and a pattern miss.
  2. PR 2 — the move. git mv each tools/tests/test_X.py to <subject's dir>/<subject>_test.py — e.g. tools/tests/test_nflib_proc.pytools/nflib/proc_test.py, tools/tests/test_poll.pytools/pr/poll_test.py, tools/tests/test_presubmit.pypresubmit_test.py at repo root; derive the full table from what is in tools/tests/ at claim time (it has grown since #494's table was written). tools/tests/fixtures/test_data/. In the same commit: flip -p "test_*.py"-p "*_test.py" and widen -s — the PR 1 guard is what makes this commit safe. Delete tools/tests/ (its one .cs, PackPresetTests.cs, was moved by #990).

Then close #494 — this chunk is its last open half — with a comment noting the C# half landed via #990's stack.

Test plan
Non-goals

Refs #494, #782, #990, #996, design 005 (S14/piece 8-9)

Dependencies

None.

Comments

No comments.

Add a comment