Design: Integration tests and OpenAPI specs
Phase 2 of 3. Derives from the approved requirements in
requirements.md.
Overview
Two conventions, one query surface:
- Scenario docstrings (R1) — a documentation convention codified in
skills/the-loop/reference/testing.md, driven by a newtestingconfig section. the-loop scenarios(R2) — a stdlib-only CLI command that extracts those docstrings and renders a table/markdown/JSON view.- Contract-first API specs (R3/R4) — a new
apiSpecsconfig section (rest: specs/openapi+graphql: specs/graphql, both with generated docs), codified in the same reference file and recorded asdecision-014.
Architecture
mermaid
flowchart LR
subgraph tests[integration tests]
T1[Python docstring] --- T2[JS/TS block comment] --- T3[Go comment]
end
CFG[.the-loop/config.yaml<br/>testing.integrationTestGlobs] --> CMD
tests -- "glob scan + marker stripping" --> EXT[the_loop/scenarios<br/>extractor]
EXT --> CMD[the-loop scenarios]
CMD --> OUT1[table] & OUT2[markdown → PR briefing] & OUT3[json → harness]Components & interfaces
cli/the_loop/scenarios/__init__.py— pure extraction library:extract_from_text(text) -> [Scenario],collect_scenarios(root, globs),DEFAULT_GLOBS. Line-based; strips comment markers (#,//,*, triple-quotes,/* */) before matchingFeature:/Scenario:/Requirement:/ step keywords — this is what makes it language-agnostic without per-language parsers.cli/the_loop/commands/scenarios.py— the registeredCommand; resolves globs (--glob>testing.integrationTestGlobs>DEFAULT_GLOBS) and renders table/markdown/json..the-loop/config.schema.json— newtestingandapiSpecssections (mirrored in the template and the repo's own config).skills/the-loop/reference/testing.md— the conventions, referenced fromSKILL.md.
Data models
Scenario { feature, scenario, requirement, steps[], file, line } — serialised as-is for --format json.
Error handling
Unreadable/undecodable files are skipped; a missing/unparsable config falls back to built-in globs with a logged warning; an empty result renders an empty table plus a warning on stderr (exit 0 — "no scenarios" is an answer, not a failure).
Testing strategy
- Extractor unit tests: Python docstring, JS block comment, feature carry-over, requirement-before and requirement-after placement.
- Command tests: registration, table and JSON output against a fixture integration test that itself follows the convention (
cli/tests/fixtures/).
Trade-offs & decisions
Text extraction over a BDD framework; spec-first over code-first APIs; SDL-first GraphQL. See docs/decisions/decision-014.md.
Open questions
- Should
the-loop scenariosgain a--checkmode that fails when an integration test has no scenario docstring (mechanical enforcement of R1)? Deferred.