Software Testing

Backend Engineering

Software Testing

Writing unit tests in Rust

Writing unit tests in Rust

Unit testing is an integral part of software development that ensures the correctness and reliability of your code's individual components (units). Rust's robust testing framework, integrated into the language through the standard std::test module, provides a powerful environment for writing and running tests. This section will explore how to write comprehensive unit tests in Rust, covering various aspects such as test organization, assertions, testing private functions, and more.

Anatomy of a Unit Test A typical Rust unit test is a function annotated with the #[test] attribute. The function should be defined within a module named tests in the same file as the code it's testing or in a separate tests.rs file within the same directory.

// File: my_module.rs

// The code to be tested
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

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

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

Assertions Rust's testing framework provides a set of assertion macros for checking conditions within your tests. The most commonly used assertions are assert_eq! and assert_ne!, which compare two values for equality or inequality, respectively.

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

Testing Private Functions Unit tests can also test private functions using the #[cfg(test)] attribute on the module containing the private function. This allows the tests to access the private function.

mod private_tests {
    // Private function to be tested
    fn multiply(a: i32, b: i32) -> i32 {
        a * b
    }

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

        #[test]
        fn test_multiply() {
            assert_eq!(multiply(2, 3), 6);
        }
    }
}

Test Organization and Modules For larger projects, organizing your tests into modules helps maintain clarity and separation of concerns. You can create nested modules to match the module structure of your code.

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

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

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

Running Tests To run your tests, use the cargo test command. By default, it discovers and runs all tests in your project.

cargo test

Testing Features and Flags Rust's testing framework provides features and flags to enhance test capabilities, such as running tests in parallel, filtering tests by name, and running only specific test modules.

  • cargo test: Runs all tests in the project.

  • cargo test -- --help: Displays available flags and options.

Test Documentation Document your tests using Rustdoc comments to provide context, examples, and usage scenarios. This documentation will help others understand the purpose and behavior of your tests.

Test Setup and Teardown Sometimes you must set up a common state or perform cleanup before and after running tests. To achieve this, Rust provides the #[before] and #[after] attributes.

Exercise

  1. Write tests for all the Rust projects you have worked on before now. Include examples and simple practice projects.

Whenever you're ready

There are 4 ways we can help you become a great backend engineer:

The MB Platform

Join 1000+ backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.

The MB Academy

The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.

Join Backend Weekly

If you like post like this, you will absolutely enjoy our exclusive weekly newsletter, Sharing exclusive backend engineering resources to help you become a great Backend Engineer.

Get Backend Jobs

Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board