Skip to main content

Testing Conventions

Where unit tests live

Unit tests are not inline. They live in crates/<crate>/src/tests/, mirroring the source path, and each source file pulls its tests in as a child module so they still see private items:

// in src/export.rs; tests in src/tests/export.rs
#[cfg(test)]
#[path = "tests/export.rs"]
mod tests;

Why: production code and tests can be measured separately with plain line counters (cloc crates --include-lang=Rust --exclude-dir=tests).

ConsequenceWhat to do
A file gets its first testsAdd the #[path] declaration (from a nested module the path climbs up, e.g. "../tests/otio/import.rs").
A source file is renamed or movedUpdate its #[path] too.
Integration testsWould go in crates/<crate>/tests/, next to src/, not in src/tests/.
Tools that walk src/Must expect the tests/ subdirectory.

Running tests

cargo test --workspace
ConstraintReason
Single-threaded (RUST_TEST_THREADS=1 in .cargo/config.toml)Graphics tests share headless GPU resources (lavapipe) and SIGSEGV intermittently in parallel.
ffmpeg binary in PATHSome tests generate synthetic clips in /tmp with the FFmpeg CLI.
A Vulkan implementationGPU tests run on lavapipe (software Vulkan) where no GPU exists.

Continuous integration

The CI workflow runs on every pull request and on pushes to master, in a fedora:44 container with RPM Fusion FFmpeg (the same packages as container/Containerfile).

StepCommand
Formatcargo fmt --check
Lintcargo clippy --all-targets -- -D warnings
Testcargo test --workspace, skipping the real-time audio pacing tests

The skipped tests measure real-time audio pacing: on the runner ALSA uses a null PCM that never blocks, so the audio clock runs far ahead of wall time.

Two clippy lints are allowed workspace-wide on purpose: too_many_arguments (wide UI/compositor signatures) and field_reassign_with_default (step-by-step Default setups).