CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/rust-unit-tests

Rust unit testing with the built-in `cargo test` harness - `#[test]` in `#[cfg(test)] mod tests` blocks, `assert_eq!` / `assert_ne!` / `assert!` macros, `#[should_panic(expected)]`, `Result<(), E>` test returns, integration tests in `tests/`, doc tests in `///` comments, runner flags (`--test-threads=1`, `--nocapture`, `--ignored`), `#[ignore]` marking, coverage via cargo-llvm-cov / tarpaulin, and Criterion benchmarks on stable. Includes framework choice (stdlib `#[test]` is the default; rstest for 4+ parameterized case pairs or shared fixtures via references) and test-authoring conventions (inline `#[cfg(test)]` placement, assertion-macro selection, async runtime requirements). References cover rstest parametrize + fixtures and Rust mocking with mockall (`#[automock]` / `mock!`). Use for any Rust unit-test task: writing tests, testing panics or Results, doc tests, coverage gates, benchmarks, or CI wiring.

72

Quality

91%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

rstest.mdreferences/

rstest - Rust parametrize + fixtures (reference)

Companion reference for rust-unit-tests. rstest adds parametrize and fixture patterns that stdlib #[test] lacks; its tests are still discovered and run by cargo test - no separate runner. Use when the same input pattern repeats across many tests, setup is shared across 3+ tests, or migrating pytest/JUnit5 habits to Rust. For single-case tests, plain #[test] needs no extra dependency.

Per github.com/la10736/rstest:

Install

[dev-dependencies]
rstest = "0.21"

Parametrize with #[case]

use rstest::rstest;

#[rstest]
#[case(1, 2, 3)]
#[case(0, 0, 0)]
#[case(-1, 1, 0)]
fn add_cases(#[case] a: i32, #[case] b: i32, #[case] expected: i32) {
    assert_eq!(add(a, b), expected);
}

Each #[case] runs as a separate test; failures don't stop subsequent cases. Name the cases - #[case::positive(1, 2, 3)] yields add_cases::positive instead of the debug-hostile case_1.

Fixtures

use rstest::{fixture, rstest};

#[fixture]
fn db() -> Database {
    Database::new_test_instance()
}

#[fixture]
fn user(db: Database) -> User {          // fixtures can chain
    db.create_user("alice")
}

#[rstest]
fn test_user_id(user: User) {            // injected by parameter name
    assert_eq!(user.id, 1);
}

Customize a fixture per test with #[default(...)] on the fixture parameter and #[with(...)] at the call site:

#[fixture]
fn user(#[default("alice")] name: &str) -> User { User::new(name) }

#[rstest]
#[case::bob("bob")]
fn test_user(#[case] expected: &str, #[with(expected)] user: User) {
    assert_eq!(user.name, expected);
}

Matrix tests (cartesian product)

#[rstest]
fn test_matrix(
    #[values("alice", "bob", "charlie")] name: &str,
    #[values(0, 18, 65)] age: u32,
) {
    let user = User::new(name, age);
    assert!(user.is_valid());
}

Runs 3 × 3 = 9 combinations. #[case] and #[values] combine (each case × each value). Watch the explosion - 5 dims × 5 values = 3125 tests; prefer strategic cases over a full matrix.

Async tests

#[rstest]
#[case(1, 2, 3)]
#[tokio::test]
async fn async_add_cases(#[case] a: i32, #[case] b: i32, #[case] expected: i32) {
    assert_eq!(add_async(a, b).await, expected);
}

Async fixtures use #[future]:

#[fixture]
async fn db_async() -> Database {
    Database::connect_async().await.unwrap()
}

#[rstest]
#[tokio::test]
async fn test_async(#[future] db_async: Database) {
    let db = db_async.await;
    assert!(db.is_connected());
}

CI

Same as plain cargo: cargo test --all-targets - rstest tests are native cargo test citizens.

Anti-patterns

Anti-patternWhy it failsFix
rstest for single-case testsDependency for no benefitPlain #[test]
Unnamed casescase_1, case_2 in failure logs#[case::name(...)]
Full matrix everywhereCombinatorial explosionStrategic cases
Mixing sync + async in one parametrizeConfusingSeparate #[rstest] blocks

References

  • rs-gh - rstest repository + docs
  • crates.io/crates/rstest / docs.rs/rstest - published crate + API

SKILL.md

tile.json