Runs the test suite with incremental line-coverage gating in one command:
mix test.qloverPlain mix test is left untouched, so single-file runs and ad-hoc flags
keep working exactly as before. mix test.qlover decides by itself:
- Baseline exists and non-test gate inputs (
priv/repo/,config/,mix.exs,mix.lock) match: runs exactly the affected test files with coverage, then gates (mix test --no-stale <files> --cover --export-coverage .qlover_fresh+mix qlover). Test-only edits stay incremental through per-test attribution. - Otherwise — first run, missing/invalid baseline, or changed
non-test inputs — runs the full suite with coverage and snapshots a
new baseline (
mix test --no-stale --cover+mix qlover --write-baseline). An info message says which path was taken.
There is no stale manifest involved: the file list comes from qlover's
own content-keyed reference graph, so selection is deterministic across
worktrees and machines, and a hostile host test alias injecting
--stale cannot shrink it (--no-stale is passed first, which wins the
duplicate-flag resolution).
Extra arguments are appended to the selection (mix test.qlover --seed 0); extra file arguments widen it, which stays sound because all
coverage still comes from one code version. The flags --stale,
--no-stale, --cover, --no-cover, --export-coverage, --failed,
--partitions, --dry-run, --no-compile are managed by the task and
rejected when passed explicitly.
Path overrides (mirroring mix qlover):
--baseline PATH- baseline file (default:cover/.qlover_baseline)--export PATH- scratch export (default:cover/.qlover_fresh.coverdata); custom paths must live under thetest_coverageoutput dir with a.coverdatasuffix.--expansion-export PATH- second scratch export accepted by the gate (default:cover/.qlover_expansion.coverdata).
Test failures abort before gating and never update the baseline. Scratch
exports are deleted after gating (and any leftovers removed before each
run), so a later mix test.coverage never unions a stale partial into a
full report. When test files change but reference data is available, only
the affected tests rerun in the focused run instead of the full
suite (see Mix.Tasks.Qlover).
The --qlover flag spelling
Mix does not let dependencies add flags to mix test, but the same
spelling is one alias away in your own mix.exs:
defp aliases do
[
test: fn
args ->
if "--qlover" in args do
Mix.Task.run("test.qlover", args -- ["--qlover"])
else
Mix.Tasks.Test.run(args)
end
end
]
endWith that, mix test --qlover gates while bare mix test (including
mix test test/foo_test.exs) stays vanilla.