Commit 6fb943a6 by PLN (Algolia)

docs(log): 044 — six suites that were green because they ran nothing

The entry for the test-hygiene sweep, written while it is fresh. Keeps the two
findings worth retelling: the assertion with an always-true escape clause that
could not fail for months, and the collection error that trained everyone to
pass --ignore and so hid a live API grading silence as tier A.
parent f1755c76
---
log: 044
title: "Six test suites that were green because they ran nothing"
date: 2026-09-05
task: "#12, #13 (+ six red tests found on master en route)"
tags: [tooling, tests, rig, api, salvage]
shareable: true
---
## Cap (what & why)
Clear the todos that needed nobody's ears. Top of the list was
`tidal-ears/tests/test_adversarial.py`, twelve audio tests that had been
reporting **twelve errors** for months. The plan was to fix one file. The file
turned out to be a symptom.
## Manœuvre (how)
The twelve were named `test_silence_vs_sound(suite)` and friends. pytest reads
that `suite` parameter as a request for a fixture, finds none, and errors — so
none of them had ever run. They also *cannot* run under pytest: each one plays
through SuperDirt on orbit 13 and captures from PipeWire. So the fix was not to
make them collectable. They became `case_*`, `main()` stayed their runner, and
the pytest tests that replaced them guard the **harness** instead of the ears —
the load-bearing one AST-reads `main()`'s own source and fails if any `case_*`
is defined but never called.
Then the same question, asked of every other test file in both repos. Five more:
| file | shape of the hollowness |
|---|---|
| `test_gain_for_stem.py` | 15 assertions at import, no `def test_*` at all — zero collected |
| `test_sc_delete.py` | 58 checks behind ONE assert, so a failure named the file, not the fault |
| `test_setlist.py` | 22 checks, same aggregate shape |
| `test_lcxl3_display.py` | (already fixed on master; a stale branch made it look hollow) |
| `test_lens.py` | pinned PLN's setlist at exactly 13 tracks |
The three import-time files kept their shape, because the prose and the
measurement belong together and reading them top-to-bottom is the point.
`check()` now records each outcome and pytest replays it, one named test per
check. All three still run as scripts.
Six instances stopped being a series of bugs and became a category, so the last
move was a guard: `tools/tests/test_suite_hygiene.py` walks every `test_*.py`
by AST — no imports, so it runs under any interpreter — and fails on a file
that collects nothing, a test whose parameter no fixture declares, or a
module-level `sys.exit()` (that one fires during *collection* and takes the
whole directory down). It floors its own file count too, because if the glob
breaks, every rule above passes vacuously.
## Prise (findings / artifacts)
- **tidal-ears `1a5d4f7`**: 9 passed / 12 errors → **83 passed / 0 errors**.
- **Tidal `7020982`, `8dd2b71`, `f1755c7`**: master was **red and unnoticed**
885 passed, 5 failed → **892 passed, 0 failed**.
- Four of those five still asserted PLN's original six-step LED ramp. The board
moved to the five-step DAYLIGHT ramp in August on his own ruling — *"top
brightness always would make more readable signals even in day perfs"* — and
the code carried that reasoning in its docstring while the tests never came
along. The six-step spec keeps a test of its own under `LCXL_DIM_RAMP=1`,
because it is still live behaviour for a dark stage.
- The fifth pinned the OPAL setlist at 13 tracks. That file is *generated* from
`backlog.md`, PLN's SSOT for set membership — it went 13 → 16 when OPAL was
logged as-performed, and the test failed for the set doing exactly what it is
supposed to do.
- **The one that matters beyond tests**: a plain `pytest` at the repo root turned
`armada/api` into 7 collection errors and then ran *nothing at all* — so the
habit became `--ignore=armada/api`, and that suite had no verdict at the root
for weeks. It had been failing. The vendored copy of the loop grader had
drifted three fixes behind the Foundry canonical, missing the **presence
gate** — so the live Fourier API would score **digital silence as tier A**.
Re-vendored; `conftest.py` now skips that tree with the exact command to run
it. Root run in the fourier venv: **993 passed**, the whole workspace, one
command.
- Verified by mutation, not by green: one planted defect per rule, each caught
by name.
## Sel (the shareable learning)
A test suite reports on the code. **Nothing reports on the suite.** Every one of
these six had looked fine for months, and each was hollow in a different way,
which is why finding one never led to finding the rest.
Two sharper edges. First, this assertion sat in the LED tests for months:
```python
assert ranks == sorted(ranks) or len(set(ranks)) == 6
```
The ramp it tested has exactly six distinct ranks, so the right-hand clause was
**always true**. The test could not fail. Any clause that can independently
satisfy an assertion is not a relaxation, it is a loophole — and the name goes
on reading as coverage forever. Worse, it was concealing something true: the
six-step ramp genuinely doubles back, which is the *measured* argument for the
ramp that replaced it. Asserting the real behaviour turned a dead test into the
best evidence for a decision already made on taste.
Second, every count in this work is pinned, because the failure being guarded
against is not a wrong answer but an **empty** one — and empty is invisible
without a number to compare against. That guard immediately caught its author:
three check-counts estimated by eye (18, 65, 28) were all wrong (15, 58, 22).
## Hameçon (hook)
*"Twelve failing tests are easy to ignore. Twelve tests that never ran are
easier — they don't fail at all."* The tell was an error count that everyone,
me included, had filed as a config nit. Following it found a live API grading
silence as excellent.
## Sillage (what it unlocks)
- The hygiene guard means the next hollow suite fails in CI instead of ageing.
- `pytest` works from the repo root again, without a flag that hides a suite —
so `armada/api` has a visible verdict for the first time in weeks.
- The grader fix is committed but **not deployed**: Fourier runs on erable and
that is PLN's call (#15). Grades already stored for silent or sparse inputs
are suspect until then.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment