Testing

For most basic code testing needs, using cargo test and std::test will be sufficient. For more advanced testing, especially property-based testing, proptest is highly recommended. mockall or faux will help when you need to mock dependencies. rstest is great for parameterized tests. And for ensuring your tests cover a good portion of your code, grcov or tarpaulin can be used.

Unit Testing

std::test (built-in) is the standard Rust testing framework for writing unit tests. Uses #[test] attribute.

Integration Testing

Often uses std::test as well, but integration tests are placed in a separate tests directory and focus on testing interactions between modules or components.

rstest is a resource-based test framework for writing data-driven tests.

This framework focuses on integration-testing, that means external software, not necessarily written in rust. rtest works by using stateful resources. It uses macros to build a executable binary that can handle all your filters and returns a nice output.

Documentation Testing

Uses #[doc = "```"] in doc comments to embed testable examples in your documentation.

Snapshot Testing: Test Your Code Against Snapshots

insta insta-crates.io insta-github insta-lib.rs cat-development-tools::testing

cargo-insta cargo-insta-crates.io cargo-insta-github cargo-insta-lib.rs cat-development-tools::cargo-plugins

Snapshots tests (also sometimes called approval tests) are tests that assert values against a reference value (the snapshot). Think of it as a supercharged version of assert_eq!. insta lets you compare the result of a test against a reference value but, unlike simple assertions, the reference value is managed by insta for you.

First, install the CLI with cargo install cargo-insta. Second, create a test, run it a first time with cargo test. This creates a snapshot file (ending with .snap). Use cargo insta review to review and accept the snapshot. Running cargo test again now succeeds, until the value returned by the function under test changes.


// Snapshot testing with the `insta` crate keeps track of how your data
// structures or output change over time.

// This is a sample function that formats user details,
// in e.g. `src/lib.rs`
pub fn format_user(name: &str, age: u32) -> String {
    format!("Name: {}, Age: {}", name, age)
}

// The following is a test that uses `insta`
// to snapshot the output, in e.g. `tests/snapshot.rs`.
// Run with `cargo test`.

use insta::assert_snapshot;

#[test]
fn test_format_user() {
    let formatted = format_user("Alice", 30);
    // If the test fails, `insta` will prompt you to review and accept the new
    // snapshot. This allows you to easily manage changes to your output
    // over time.
    assert_snapshot!("format_user_snapshot", formatted);
}

Asynchronous Testing

Often involves using tokio::test or similar runtime-specific attributes for testing asynchronous code.