Each top-level tests/*.rs was its own crate → its own binary, each statically linking the bundled engine + every dep. 26 of them, so an edit to the lib relinked all 26. Moved the 25 standalone files into tests/it/ under one tests/it/main.rs (the pattern typing_surface already uses); cargo auto-detects it as the `it` target. End state: 2 integration-test binaries instead of 26. Result: target/debug/deps 1.5 GB → 629 MB (-58%). Build time barely moved (clean 22.9s→22.4s, lib-edit relink 13.3s→12.4s) — wall-clock is dominated by compiling, not linking, so this is a disk win, not a speed win (see docs/plans/20260602-test-consolidation.md). Tests unchanged at 2151/0/1; clippy clean; no fixups needed. typing_surface_matrix stays its own already-consolidated binary. Tradeoff: the 25 files now share one crate (a compile error fails the whole `it` binary; module-scoped namespaces, no clashes) — negligible for a solo project.
3.5 KiB
Plan: consolidate integration tests into one binary
Date: 2026-06-02 · Status: done
Outcome (measured)
| Metric | Before | After |
|---|---|---|
target/debug/deps |
1.5 GB | 629 MB (−58%) |
| Integration-test binaries | 26 | 2 (it + typing_surface_matrix) |
| Clean test build | 22.9 s | 22.4 s |
| Lib-edit relink | 13.3 s | 12.4 s |
| Tests | 2151/0/1 | 2151/0/1 (identical) |
cargo auto-detected tests/it/main.rs as the it target — no
[[test]] entry, no fixups, no warnings.
Correction to the build-time hypothesis: the expected relink
speed-up (≈13 s → ≈5 s) did not materialise. Wall-clock is dominated
by compiling (the lib + ~290 deps + the test code's
codegen/monomorphisation), not by linking. Consolidation collapses 26
link steps into 2 — which is why disk drops 58 % (each link emits a
whole standalone binary) — but compile work is unchanged, so build time
barely moves. The real, durable win is disk, not speed. Minor cost:
editing a single test file now recompiles the whole it module set
(test-only edits marginally slower; lib edits marginally faster — a
wash). Kept for the disk benefit, which is exactly the concern that
prompted it.
Why
Each top-level tests/*.rs is a separate integration-test crate →
its own binary, each statically linking the bundled engine + every
dependency + debug info. There are 26 of them. With incremental
disabled (build-hygiene change, commit 42f9553), an edit to the lib
forces all 26 to relink.
Measured baseline:
- Lib-edit relink (touch
src/app.rs,cargo test --no-run): 13.3 s - Clean build of all test targets (
cargo clean && cargo test --no-run): 22.9 s target/debug/deps: 1.5 GB
Collapsing to one binary turns 26 links into 1 — the dominant cost in both numbers.
Approach
The pattern already used by tests/typing_surface_matrix.rs (one
binary that mod-includes the tests/typing_surface/ modules). Apply
it to the other 25 standalone files.
Feasibility pre-checks (done, all clear):
- No top-level integration test uses insta → moving files causes no snapshot-path churn.
- No crate-level
#![…]attributes to hoist. - No shared
mod common;helpers to relocate; the 25 files are self-contained (use rdbms_playground::…), no inter-filemod.
Steps
mkdir tests/it.git mvthe 25 standalonetests/*.rs→tests/it/<name>.rs(everything excepttyping_surface_matrix.rs, which stays as its own already-consolidated binary).- Create
tests/it/main.rs=mod <name>;for all 25. - Confirm cargo builds it as one target (
tests/it/main.rsauto-detection; add an explicit[[test]] name="it"only if not). - Fix anything the combined build surfaces (expected minimal): a
stray
use crate::self-ref, or a clippydead_code/unused-import the per-crate split had hidden.
End state: 2 integration-test binaries (it + typing_surface_matrix)
instead of 26.
Verification / go-no-go gate
- Full
cargo test→ identical 2151 / 0 / 1. cargo clippy --all-targets -- -D warningsclean.- Re-measure relink + clean build; record before/after in the commit.
- If the after-numbers aren't materially better, revert (all
git mv, trivially reversible).
Tradeoff (accepted)
Lose per-crate isolation: a compile error fails the whole it binary,
and the 25 files share one crate namespace (module-scoped — no name
clashes). Negligible for a solo teaching project; the build-speed win
is the priority.