DEV Community

Subesh Yadav
Subesh Yadav

Posted on

Day 21 of #100DaysOfRust: Organizing and Running Tests in Rust

Welcome to Day 21 of my Rust journey! Today, I delved deep into the mechanisms Rust provides for organizing and running tests. Yesterday, I explored writing test functions and macros like assert!, assert_eq!, and assert_ne!. Today was about running those tests efficiently, filtering and organizing them, and understanding the distinctions between unit and integration tests.

🧪 How Rust Runs Tests

Rust’s cargo test command compiles your code in test mode and runs the resultant test binary. By default, it:

  • Runs all tests in parallel using threads.
  • Captures output of passing tests for a cleaner report.

You can customize this behavior using:

  • cargo test --help: View Cargo’s test options.
  • cargo test -- --help: View options passed to the test binary.

🧵 Running Tests in Parallel or Consecutively

Rust runs tests in parallel by default to speed up feedback. But this can cause issues if tests share state (e.g., the same file, directory, environment variables).

Avoid shared state or use:

cargo test -- --test-threads=1
Enter fullscreen mode Exit fullscreen mode

This command disables parallelism and runs tests serially.


👁 Showing Output for Passing Tests

By default, output (println!) in passing tests is hidden.

To view it:

cargo test -- --show-output
Enter fullscreen mode Exit fullscreen mode

Example

fn prints_and_returns_10(a: i32) -> i32 {
    println!("I got the value {a}");
    10
}

#[test]
fn this_test_will_pass() {
    let value = prints_and_returns_10(4);
    assert_eq!(value, 10);
}
Enter fullscreen mode Exit fullscreen mode

Use --show-output to view the printed output.


🎯 Running a Subset of Tests by Name

You don’t have to run all tests.

Run a single test:

cargo test one_hundred
Enter fullscreen mode Exit fullscreen mode

Example:

#[test]
fn one_hundred() {
    assert_eq!(100, 10 * 10);
}
Enter fullscreen mode Exit fullscreen mode

Run tests with partial name match:

cargo test add
Enter fullscreen mode Exit fullscreen mode

This runs all tests with add in the name.

Example:

#[test]
fn add_two_numbers() {
    assert_eq!(2 + 2, 4);
}

#[test]
fn add_three_numbers() {
    assert_eq!(1 + 2 + 3, 6);
}
Enter fullscreen mode Exit fullscreen mode

🔕 Ignoring Expensive Tests

You can ignore long-running tests by default and run them only when needed.

#[test]
#[ignore]
fn expensive_test() {
    // takes time
}
Enter fullscreen mode Exit fullscreen mode

Run ignored tests only:

cargo test -- --ignored
Enter fullscreen mode Exit fullscreen mode

Run all tests including ignored:

cargo test -- --include-ignored
Enter fullscreen mode Exit fullscreen mode

🗂 Test Organization: Unit Tests vs Integration Tests

🧪 Unit Tests

  • Placed inside src/ next to the code.
  • Use #[cfg(test)] to compile only during testing.
  • Access private items.
// src/lib.rs
pub fn add(x: u32, y: u32) -> u32 {
    x + y
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        assert_eq!(add(2, 2), 4);
    }
}
Enter fullscreen mode Exit fullscreen mode

🧩 Integration Tests

  • Placed in tests/ directory.
  • Compiled as separate crates.
  • Only access public API.

Example:

// tests/integration_test.rs
use my_crate::add;

#[test]
fn it_adds_two() {
    assert_eq!(add(2, 2), 4);
}
Enter fullscreen mode Exit fullscreen mode

🧱 Shared Setup for Integration Tests

Put reusable code in tests/common/mod.rs:

// tests/common/mod.rs
pub fn setup() {
    // Setup code here
}
Enter fullscreen mode Exit fullscreen mode

Use it like this:

mod common;

#[test]
fn it_adds_two() {
    common::setup();
    assert_eq!(add(2, 2), 4);
}
Enter fullscreen mode Exit fullscreen mode

🧠 Summary

  • Rust allows parallel and serial test execution.
  • Use filtering to speed up your workflow.
  • Structure matters: unit vs integration.
  • Output visibility, ignored tests, and subsetting are all customizable.
  • Integration tests live in their own crates under tests/.

That’s all for today.

Top comments (0)