cargo-test-filter 0.1.1

A cargo subcommand for intelligent test filtering and compilation
Documentation
# 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 test` runs 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](https://github.com/rust-lang/cargo/issues/8396) and [#8282](https://github.com/rust-lang/cargo/issues/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

```bash
cargo install cargo-test-filter
```

Or build from source:

```bash
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):

```rust
// @tag: fast
// @tag: api
#[test]
fn test_api_endpoint() {
    // ...
}

// @tag: slow
// @tag: database
#[test]
fn test_database_migration() {
    // ...
}
```

Or use attribute syntax:

```rust
#[test_tag("fast")]
#[test]
fn test_quick_calculation() {
    // ...
}
```

### Run Filtered Tests

```bash
# 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 in `tests/` directory)
- **`--unit`**: Run only unit tests (tests in `src/` 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:

```rust
// 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

```yaml
# 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

```bash
# 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

```bash
$ 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

1. **Discovery**: Scans `tests/` and `src/` directories for test files
2. **Parsing**: Extracts individual test functions and their associated tags
3. **Filtering**: Applies your filter criteria at the function level
4. **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