2 releases
| 0.1.1 | Dec 22, 2025 |
|---|---|
| 0.1.0 | Dec 22, 2025 |
#248 in Cargo plugins
50KB
957 lines
cargo-test-filter
A cargo subcommand for intelligent test filtering. Run only the tests you need—by tag, type, or pattern.
Problem
Cargo's built-in test filtering has limitations:
- No way to isolate test types:
cargo testruns both unit and integration tests together - String prefix matching only: No semantic filtering by tags or attributes
- No function-level tag filtering: You can't tag individual tests and run only tagged ones
GitHub issues #8396 and #8282 document these pain points.
Solution
cargo-test-filter provides function-level test filtering with:
- Type isolation: Run only integration tests or only unit tests
- Tag-based filtering: Mark tests with tags and run only what you need
- Pattern matching: Filter by test name or path patterns
- Test discovery: List all tests with their tags before running
Installation
cargo install cargo-test-filter
Or build from source:
git clone https://github.com/johnproblems/cargo-test-filter
cd cargo-test-filter
cargo install --path .
Quick Start
Tag Your Tests
Use comment-based tags (no proc macros required):
// @tag: fast
// @tag: api
#[test]
fn test_api_endpoint() {
// ...
}
// @tag: slow
// @tag: database
#[test]
fn test_database_migration() {
// ...
}
Or use attribute syntax:
#[test_tag("fast")]
#[test]
fn test_quick_calculation() {
// ...
}
Run Filtered Tests
# Run only tests tagged "fast"
cargo test-filter --tag fast
# Run only integration tests
cargo test-filter --integration
# Run unit tests excluding slow ones
cargo test-filter --unit --exclude-tag slow
# List all tests with their tags
cargo test-filter --list
# Filter by test name pattern
cargo test-filter --name api
# Combine filters
cargo test-filter --integration --tag database
Features
Implemented
--integration: Run only integration tests (tests intests/directory)--unit: Run only unit tests (tests insrc/files)--tag <TAG>: Filter by tag (comma-separated for multiple:--tag fast,api)--exclude-tag <TAG>: Exclude tests with these tags--name <PATTERN>: Filter tests by name pattern--path <PATTERN>: Filter tests by file path pattern--list: List matching tests without running them-v, --verbose: Show detailed output including discovered tests and timing- Function-level filtering: Tags are associated with individual test functions, not files
Tag Syntax
Two formats are supported:
// Comment-based (recommended - no dependencies needed)
// @tag: fast
#[test]
fn my_test() {}
// Attribute-based
#[test_tag("fast")]
#[test]
fn my_test() {}
Tags must appear immediately before the #[test] attribute.
Usage Examples
CI Pipeline
# GitHub Actions example
jobs:
fast-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run fast tests
run: cargo test-filter --tag fast
integration-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run integration tests
run: cargo test-filter --integration
slow-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run slow tests
run: cargo test-filter --tag slow
Development Workflow
# Quick iteration - run only fast tests
cargo test-filter --tag fast
# Before commit - run everything except slow tests
cargo test-filter --exclude-tag slow
# Debug a specific area
cargo test-filter --name auth --verbose
# See what tests exist
cargo test-filter --list
cargo test-filter --tag database --list
Verbose Output
$ cargo test-filter --tag fast -v
cargo-test-filter v0.1.0
Filters: tags: fast
Project root: /home/user/my-project
Discovered 25 test function(s) in 45.23ms
- api_test::test_fast_endpoint (tags: ["fast", "api"])
- db_test::test_quick_query (tags: ["fast", "database"])
- lib::test_calculation (tags: ["fast", "unit"])
...
Filtered to 3 test function(s)
Running 3 test function(s)...
How It Works
- Discovery: Scans
tests/andsrc/directories for test files - Parsing: Extracts individual test functions and their associated tags
- Filtering: Applies your filter criteria at the function level
- Execution: Runs only matching tests using
cargo test --exact
Unlike file-level filtering, this tool identifies which specific test functions match your criteria, so if you have 10 tests in a file and only 2 are tagged "fast", only those 2 will run.
Comparison with cargo test
| Feature | cargo test |
cargo test-filter |
|---|---|---|
| Filter by test type | Limited (--lib, --test) |
Yes (--integration, --unit) |
| Tag-based filtering | No | Yes |
| Function-level tags | No | Yes |
| Exclude by tag | No | Yes (--exclude-tag) |
| List tests with tags | No | Yes (--list) |
| Pass-through args | Yes | Yes |
Limitations
- Compile time: Tests in matching files are still compiled (Rust compiles at the file level). The tool optimizes which tests run, not compilation.
- Doc tests: Not yet supported
- Workspaces: Currently works in single-crate projects
- Async test frameworks: Supports
#[tokio::test]and#[async_std::test]detection
CLI Reference
cargo test-filter [OPTIONS]
Options:
--integration Run only integration tests
--unit Run only unit tests
--tag <TAG> Filter by tag (comma-separated)
--exclude-tag <TAG> Exclude tests with these tags
--name <PATTERN> Filter by test name pattern
--path <PATTERN> Filter by file path pattern
--list List matching tests without running
--timeout <SECS> Test timeout in seconds (planned)
-v, --verbose Show verbose output
-h, --help Print help
-V, --version Print version
Additional arguments after -- are passed to cargo test.
Contributing
Contributions welcome! Areas for improvement:
- Workspace support
- Doc test filtering
- JSON output for CI integration
- Per-test timeout enforcement
- IDE integration (rust-analyzer hints)
License
MIT OR Apache-2.0
Dependencies
~3–6.5MB
~120K SLoC