oxitest Architecture Map
Interactive visual overview of the pipeline, data structures, design patterns, and component interactions. Click any element to expand details.
Pipeline Stages
Each stage is a variant of the PipelinePhase enum. Transitions consume the pipeline and produce a new one with the next variant — calling phases out of order triggers an unreachable! panic.
Phase 0
Empty
PipelinePhase::Empty
Entry point; no data yet
Phase 1
FilesCollected
PipelinePhase::FilesCollected
Test files and conftest files discovered via globset
Phase 2
Prescanned
PipelinePhase::Prescanned
AST-based metadata extracted without importing Python
Phase 3
MetadataFiltered
PipelinePhase::MetadataFiltered
Modules pruned by -E query DSL before Python import
Phase 4
SessionReady
PipelinePhase::SessionReady
FixtureSession built from conftest chain
Phase 5
Collected
PipelinePhase::Collected
Python modules imported; TestItems created
Phase 6
Ready
PipelinePhase::Ready
Strict validation + item-level filtering applied; ready for execution
Phase 7
Executed
PipelinePhase::Executed
All tests run; results and timings collected
Empty → collect_files()
(unit struct)No fields — this is the entry point
FilesCollected → affected(), prescan()
test_files : Vec<Utf8PathBuf>Discovered test file paths
conftest_files : Vec<Utf8PathBuf>Discovered conftest.py paths
Prescanned → filter_metadata()
test_files : Vec<Utf8PathBuf>Test file paths (possibly filtered by --affected)
conftest_files : Vec<Utf8PathBuf>Conftest paths
prescan_data : Vec<PrescanResult>Per-file AST scan results (function names, markers, parametrize IDs)
module_markers : HashMap<...>Markers grouped by module for fast filtering
MetadataFiltered → session()
test_files : Vec<Utf8PathBuf>Test file paths
conftest_files : Vec<Utf8PathBuf>Pruned conftest chain
modules_to_import : Vec<Utf8PathBuf>Only modules surviving metadata filtering
is_filtered : boolWhether any metadata filter was applied
SessionReady → collect()
test_files : Vec<Utf8PathBuf>Test file paths
conftest_files : Vec<Utf8PathBuf>Conftest paths
session : Py<PyAny>Python FixtureSession object
session_violations : Vec<RawViolation>Violations from conftest loading
Collected → validate(), strict_or_skip()
items : Vec<Arc<TestItem>>Collected test items from Python import
raw_violations : Vec<RawViolation>Combined session + collection violations
session : FixtureSessionPython FixtureSession object
Ready → strict_or_skip()
session : FixtureSessionPython FixtureSession object
clean_items : Vec<Arc<TestItem>>Items passing strict-mode and filter checks
violated_items : Vec<Arc<TestItem>>Items with strict-mode violations
all_violations : Vec<StrictViolation>All accumulated violations
suite_lines : Vec<String>Formatted strict violation output lines
Executed → retry(), finalize()
items : Vec<Arc<TestItem>>All executed test items
execution_results : ExecutionResultsPer-test outcomes, timings, and diagnostics
session : Py<PyAny>Python FixtureSession (for teardown)
Key Data Structures
Click a card to expand its fields. Connections show which other structures it references.
Design Patterns
Phase Enum Machine
Pipeline holds a PipelinePhase enum. Each transition guards on the expected variant with let ... else { unreachable! } and produces the next variant.
Empty → FilesCollected → ... → Executed (variants of PipelinePhase)
Read docs →
Trait-Based Plugin System
Reporter, FixtureProvider, ExecutionWrapper, and CoverageProvider traits define stable extension points. Provisional traits (Collector, LogBackend, AsyncBackend, DebuggerBackend) are unstable.
trait Reporter { fn on_test_start(); fn on_test_end(); ... }
Read docs →
Strategy Pattern
ExecutionDispatch enum abstracts over serial vs parallel execution. Serial and Parallel variants carry their own data and dispatch via match — no dynamic dispatch needed.
enum ExecutionDispatch { Serial { ... }, Parallel { ... } }
Read docs →
Builder Pattern
ReporterOptsBuilder accumulates reporter configuration across pipeline phases before building the final ReporterOpts at execution time.
ReporterOptsBuilder → .with_total() → .with_timing() → .build()
Read docs →
PyO3 Bridge
Rust-Python boundary via PyO3. TestResult and CollectedItem are #[derive(FromPyObject)] structs that must stay in sync with Python counterparts in result.py.
bridge.rs ↔ python/oxitest/_bridge/result.py
Read docs →
Newtype Wrappers
NodeId, DurationMs, ExitCode wrap primitives to prevent accidental mixing and provide domain-specific methods.
struct NodeId(String); struct DurationMs(f64);
Read docs →
Key Traits
Reporter
src/reporter/traits.rs
Receives lifecycle events during test execution. Multiple reporters are multiplexed. TTY, CI, JSON, JUnit, and plugin reporters implement this.
fn on_session_start(&mut self)
fn on_test_start(&mut self, item: &TestItem)
fn on_test_end(&mut self, item: &TestItem, outcome: &TestOutcome)
fn on_session_end(&mut self) → ExitVote
ExecutionDispatch
src/pipeline/execution.rs
Enum dispatching serial vs parallel test execution. Serial variant runs tests in-process; Parallel variant delegates to worker subprocesses. No dynamic dispatch needed.
fn execute_groups(&mut self, groups: Vec<ModuleGroup>, rep: &mut dyn Reporter) → PhaseResult
TimingCache
src/cache/timing.rs
Per-test duration lookup for heaviest-first scheduling. Used by the scheduler to balance work across parallel workers.
fn estimated_duration(&self, node_id: &NodeId) → Option<DurationMs>
OutcomeCache
src/cache/outcome.rs
Last-outcome and flaky-count lookup. Powers --lf (last-failed) and --ff (failed-first) filtering.
fn last_outcome(&self, node_id: &NodeId) → Option<TestOutcome>
fn flaky_count(&self, node_id: &NodeId) → u32
FixtureSession
python/oxitest/_bridge/_fixture_session.py
Python-side fixture lifecycle management. Scope-based caching (function, module, session), yield teardown, autouse injection.
def resolve(self, name: str, scope: Scope) → Any
def teardown(self, scope: Scope) → None
Component Interaction Map
Hover over nodes for details. Click to navigate to the relevant documentation page.