Auto-diagnose test gaps from file changes and track test outcomes
Overview
Fix-test keeps a project's tests in step with its source. It turns file-system events into a prioritized, partly auto-executable maintenance plan, and it records what actually ran so the next plan can reason about staleness and coverage gaps.
Two modules cooperate:
test_maintenanceowns planning.TestMaintenanceWorkflowinspects file events and produces aTestMaintenancePlan— an ordered set ofTestPlanItementries, each describing one piece of test work (which file, whatTestAction, at whatTestPriority).test_runnerowns measurement. Standalone functions (run_tests_with_tracking,track_coverage,track_file_tests) execute tests and persist the results as telemetry records, and query functions (get_file_test_status,get_files_needing_tests) read those records back.
Fix-test is not a test generator — it decides what test work a
change implies and whether it can run unattended. It is reached as
the /fix-test skill; there is no dedicated attune CLI subcommand.
This page documents the Python API you call directly when wiring test
maintenance into a hook, a CI step, or a custom tool.
Concepts
From a file event to a plan
TestMaintenanceWorkflow is the coordinator. Construct it with a
project root, then drive it one of two ways:
- Event handlers —
on_file_created,on_file_modified, andon_file_deletedeach take a singlefile_pathand return a dict describing the test work that change implies. These are the integration point for a file-watcher or a git hook. run(context)— generates a whole-projectTestMaintenancePlanin one of four modes (analyze,execute,auto,report).
Both paths lean on the same building blocks:
| Type | What it represents |
|---|---|
TestPlanItem |
One unit of test work: file_path, the action (TestAction), the priority (TestPriority), a reason, an optional test_file_path, an estimated_effort string, an auto_executable flag, and a free-form metadata dict. |
TestMaintenancePlan |
The assembled plan: generated_at, the list of items, a summary dict, and options. Filter it with get_items_by_action, get_items_by_priority, or get_auto_executable_items. |
TestAction |
What to do with a test — one of CREATE, UPDATE, REVIEW, DELETE, SKIP, MANUAL. |
TestPriority |
How urgent — one of CRITICAL, HIGH, MEDIUM, LOW, DEFERRED. |
The two modules fit together
- Planning (
test_maintenance) answers "given this change, what test work is needed and how urgent is it?" It is index-backed: the workflow holds aProjectIndexand refreshes it when files change, so impact and staleness drive the priorities it assigns. - Measurement (
test_runner) answers "what did the tests actually do?" Its functions run pytest (or a custom command), parse the results, and writeTestExecutionRecord,CoverageRecord, andFileTestRecordentries into the telemetry store. The query functions then surface "is this file covered?" and "what still needs tests?" — the same signals the workflow'sget_stale_testsandget_test_health_summarysummarize.
Async vs sync — the one thing to get right
The workflow's event and run surface is asynchronous; everything else is a plain function call:
async—run,on_file_created,on_file_modified,on_file_deleted.awaitthem (or drive withasyncio.run).- sync — the plan-filter methods (
get_items_by_action, …), the workflow's summary methods (get_files_needing_tests,get_stale_tests,get_test_health_summary), and everytest_runnerfunction.
Two functions named get_files_needing_tests
Mind the namespace: there is a module-level
test_runner.get_files_needing_tests(stale_only=False, failed_only=False) that reads telemetry records, and a
TestMaintenanceWorkflow.get_files_needing_tests(limit=20) method that
reads the project index. They are different functions with different
signatures and return types — import or call the one you mean.