Sling Academy
Home/Rust/Running Tests in Rust Using the cargo test Command

Running Tests in Rust Using the cargo test Command

Last updated: January 06, 2025

Rust is a systems programming language designed for performance and safety, particularly safe concurrency. In the Rust ecosystem, testing is a crucial aspect of the development workflow. Rust's built-in test framework is integrated into the cargo tool and the cargo test command is a powerful way to execute these tests.

Introduction to Rust Testing

Testing in Rust can be managed directly using the Rust package manager, Cargo. It allows developers to ensure that their code behaves as expected and aids in automatically verifying code functionality.

Writing Your First Test

Let's start by writing a simple function in Rust and a test to validate its behavior. Here’s a small function that adds two numbers:

pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

To test this function, you need to create a module in your Rust source file where your test functions will reside. This module will be marked with the #[cfg(test)] attribute which tells the compiler to include this test code only when you run cargo test.

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

    #[test]
    fn test_add() {
        assert_eq!(add(2, 3), 5);
    }
}

Inside the test module:

  • We import the parent module using use super::*;.
  • The # [test] attribute marks the test_add function as a test.
  • The function checks whether add(2, 3) equals 5 using assert_eq!.

Running Tests with Cargo

To execute the tests, use:

$ cargo test

This command will build and run the tests. You will see output informing you of the pass/fail status of your tests:

running 1 test
    test tests::test_add ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Understanding Test Output

By default, cargo test runs in parallel, capturing and suppressing the test's standard output unless a test fails. If you want to see the standard output printed during passing tests, run:

$ cargo test -- --nocapture

Additionally, you can filter which tests to run by providing a substring of the test's name:

$ cargo test test_add

This feature allows more targeted testing, running only those tests that match the given substring.

Test Organization and Structure

Tests in Rust can be organized in three forms:

  • Unit Tests: Testing individual functions or modules. Placed in the same files as functions being tested within a #[cfg(test)] module.
  • Integration Tests: Found in the tests directory, treating each .rs file as a crate.
  • Documentation Tests: Embed test code within the function's documentation comments and run them using cargo test.

Ignoring Tests

If a test needs to be ignored (perhaps for reasons of long runtimes or incomplete status), you can do so with the #[ignore] attribute. To run ignored tests, use the following:

$ cargo test -- --ignored

Conclusion

Rust's testing framework, powerfully integrated with Cargo, aids developers in maintaining high code quality. Through efficient test cases, captured outputs, and organized structures, cargo test becomes an indispensable tool in the Rust development toolbox.

Next Article: Organizing Rust Test Files and Modules for Clarity and Maintainability

Previous Article: Writing Basic Unit Tests in Rust with the #[test] Attribute

Series: Testing in Rust

Rust

You May Also Like

  • E0557 in Rust: Feature Has Been Removed or Is Unavailable in the Stable Channel
  • Network Protocol Handling Concurrency in Rust with async/await
  • Using the anyhow and thiserror Crates for Better Rust Error Tests
  • Rust - Investigating partial moves when pattern matching on vector or HashMap elements
  • Rust - Handling nested or hierarchical HashMaps for complex data relationships
  • Rust - Combining multiple HashMaps by merging keys and values
  • Composing Functionality in Rust Through Multiple Trait Bounds
  • E0437 in Rust: Unexpected `#` in macro invocation or attribute
  • Integrating I/O and Networking in Rust’s Async Concurrency
  • E0178 in Rust: Conflicting implementations of the same trait for a type
  • Utilizing a Reactor Pattern in Rust for Event-Driven Architectures
  • Parallelizing CPU-Intensive Work with Rust’s rayon Crate
  • Managing WebSocket Connections in Rust for Real-Time Apps
  • Downloading Files in Rust via HTTP for CLI Tools
  • Mocking Network Calls in Rust Tests with the surf or reqwest Crates
  • Rust - Designing advanced concurrency abstractions using generic channels or locks
  • Managing code expansion in debug builds with heavy usage of generics in Rust
  • Implementing parse-from-string logic for generic numeric types in Rust
  • Rust.- Refining trait bounds at implementation time for more specialized behavior