Testing: the validation suite
Run it
just test
# or
python3 tests/validate.py It runs from anywhere and needs only Python 3 (no third-party packages, no network). It prints one line per check and exits non-zero if any check fails, so it works in CI and as a pre-commit hook.
What it checks
- The expected topic count (the constant at the top of the script).
- Contiguous numbering within each part, starting at N.0.
- H1 matches the file name decimal for every topic.
- H1 titles match
spec/structure.mdcharacter for character, not just the leading decimal. - Required sections are present in every content topic (Parts 1 through 8, topic N.1 and up), in exactly the template order.
- A minimum word count for every content topic (1,500 words), with an allowlist in the script for intentional exceptions.
- No em-dashes in any Markdown file.
- En-dashes only between digits, so “2.1–2.8” passes and everything else fails.
- No forbidden phrases (“not only”, “but also”, “load-bearing”).
- All internal
.mdlinks resolve. - Prose cross-references point at real topics: a reference to a topic number with no matching file on disk fails, using the same reference pattern the published site’s topic-link auto-linking uses.
- Wikipedia links are well-formed (
https://en.wikipedia.org/wiki/...). spec/structure.mdmatches the files on disk, in both directions.- README, the home page, and the contents page link every topic.
When a check fails
The failing line names the file and the problem. Common fixes:
- Em-dash found: reword the sentence to remove the ”—“. Do not just delete it.
- Missing section: add the missing
##section from the topic template. - Structure mismatch: you added or renamed a topic without updating
spec/structure.md, or vice versa. Bring them back in line. - Broken link: fix the path, or update it after a rename.
- Numbering gap: renumber so the part is contiguous from N.0.
Beyond the validation suite
just spellruns codespell over the repository. The configuration, including the false-positive ignore list, is the[tool.codespell]section inpyproject.toml.just statsprints a Markdown report (per-topic word counts, thin topics, Wikipedia links, reference entries) fromtools/stats.py.
Continuous integration
.github/workflows/test.ymlruns on every pull request and on pushes to non-main branches: the validation suite and codespell. This repository does not build or deploy a site; rendering happens in the separatesoftware-engineering-metrics.github.iorepository..github/workflows/links.ymlchecks external links weekly with lychee (ignore patterns in.lycheeignore) and keeps the results in a single “Link checker report” issue. External links stay out of the PR path on purpose.
Not covered by the tests
The suite checks structure and style, not truth. It cannot tell whether a reference is real or whether prose is accurate. Verify citations and facts by hand or with a research pass. Wikipedia link existence (as opposed to link form) also needs a network check, which the suite deliberately leaves out so it can run offline.