How to Run Tests for Headroom: Complete Guide for Python and Rust

To run tests for Headroom, set up a Python virtual environment, install dev dependencies with pip install -e .[dev], build the Rust extension using scripts/build_rust_extension.sh, and execute make ci-precheck-python to replicate CI behavior.

Headroom is a hybrid Python/Rust audio processing library that requires a compiled core extension (headroom._core) to function. Because the codebase spans both languages, the test suite comprises pytest for Python components and cargo test for Rust internals. The repository provides a Makefile that orchestrates these dependencies, ensuring your local results match the automated CI pipeline exactly.

Prerequisites

Before executing any test commands, you need both Python and Rust toolchains configured on your system.

Python Virtual Environment

Headroom enforces virtual environment isolation. The Makefile checks for the $$VIRTUAL_ENV variable and aborts if you attempt to run tests outside an activated venv. Create and activate one with:

python3 -m venv .venv
source .venv/bin/activate

Rust Toolchain

The Rust extension requires maturin for building Python bindings. While the scripts/build_rust_extension.sh wrapper handles the build process, ensure you have Rust installed (via rustup) to compile the crates/headroom-py crate.

Step-by-Step Test Execution

Install Development Dependencies

Install Headroom in editable mode along with the test runner and coverage tools defined in pyproject.toml:

pip install -e .[dev]

This installs pytest, pytest-asyncio, pytest-cov, and other extras required by the test suite in tests/.

Build the Rust Extension

Many transforms—such as SmartCrusher and DiffCompressor—import the compiled headroom._core module. Without this extension, Python tests will skip or fail with import errors. Build it using the provided script:

bash scripts/build_rust_extension.sh

This script invokes maturin to compile the Rust core and makes it importable from your Python environment.

Run the Curated Python Test Suite

Execute the CI-equivalent test target to run only the critical, fast tests:

make ci-precheck-python

According to the Makefile (lines 94-107), this target:

  1. Rebuilds the Rust extension to ensure the latest code is tested
  2. Runs pytest on a curated list of core test files (e.g., tests/test_transforms/test_smart_crusher_bugs.py)
  3. Excludes slower integration tests to provide rapid feedback

You should see output similar to:


── ci-precheck-python ─────────────────────────────────────────
============================= test session starts ==============================
collected 123 items

tests/test_transforms/test_smart_crusher_bugs.py ..                      [  2%]
...
============================== 123 passed in 4.57s ==============================
✅ ci-precheck PASSED — safe to push.

Run the Full Rust Test Suite

To validate the underlying Rust implementation directly, use the Cargo workspace command:

make test

This executes cargo test --workspace across all crates in the repository, including the core algorithms exposed to Python.

Advanced Testing Options

Run Parity Tests

Headroom maintains parity fixtures that verify Rust and Python compressors produce identical output. Run these cross-language integration tests with:

make test-parity

As defined in the Makefile (lines 35-42), this target builds the extension with maturin develop and executes comparison tests between the native Rust and Python implementations.

Run Full Python Test Suite

If you need to execute every test in the tests/ directory—including slower integration tests—invoke pytest directly:

pytest -q

Note that this bypasses the CI optimization and may include flaky or heavyweight tests not required for every commit.

Understanding the Test Architecture

Why the Rust Extension is Required

The headroom._core module contains performance-critical audio processing logic written in Rust. When you import transforms like SmartCrusher in Python, they delegate to this compiled extension. The scripts/build_rust_extension.sh ensures this binary is present before Python tests execute, mirroring the CI workflow's build steps.

CI vs. Local Development

The ci-precheck-python target intentionally limits the test scope to a subset of files that must remain green on every push. This selective approach keeps feedback fast while the Makefile guarantees the Rust extension is always fresh. For comprehensive validation across both languages, combine make test (Rust) with make ci-precheck-python (Python).

Summary

  • Create a virtual environment and activate it before running any make targets, as the repository enforces $$VIRTUAL_ENV checks.
  • Install dependencies using pip install -e .[dev] to obtain pytest and coverage tools from pyproject.toml.
  • Build the Rust extension via scripts/build_rust_extension.sh to compile headroom._core with maturin.
  • Run curated tests using make ci-precheck-python to replicate the CI pipeline and validate critical Python components.
  • Validate Rust code with make test which executes cargo test --workspace across the crate directory.
  • Check cross-language parity using make test-parity to ensure Rust and Python implementations produce identical results.

Frequently Asked Questions

Why do I need to build a Rust extension to run Python tests?

Headroom's Python API relies on the headroom._core module, a compiled Rust extension that provides high-performance audio processing primitives. Many tests in tests/test_transforms/ import transforms that delegate to this native code. Without building the extension via scripts/build_rust_extension.sh, these imports fail and the corresponding tests are skipped or error out.

What is the difference between make ci-precheck-python and running pytest directly?

The ci-precheck-python target runs a curated subset of tests defined in the Makefile that represent the "must-pass" criteria for every commit, excluding slower integration tests. Running pytest -q directly executes every file in the tests/ directory, including heavyweight parity and integration tests that may take significantly longer and are not required for rapid development feedback.

How do I run tests for only the Rust components?

Execute make test from the repository root. This command runs cargo test --workspace across all Rust crates in the project, including the core algorithms in crates/headroom-py and any associated libraries, without requiring Python environment setup.

Can I run tests without using the Makefile?

Yes, but you must manually replicate the dependency chain. First ensure your virtual environment is active and dependencies are installed, then build the Rust extension with bash scripts/build_rust_extension.sh, and finally run pytest with your desired flags. However, the Makefile handles these steps automatically and enforces the same environment checks used in CI, making it the recommended approach for consistent results.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →