Testing in Rust: Frameworks and Tools

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Testing in Rust: Frameworks and Tools



Rust is a systems programming language that places a huge emphasis on reliability and safety. Its built-in testing system is one of the key features, allowing you to write quality code without needing to install third-party frameworks. In this article, we will take a detailed look at the main tools for testing in Rust: from simple unit tests to complex property-based tests and benchmarks.



Built-in Testing Framework



In Rust, tests are run using the cargo test command. Tests are regular functions marked with the #[test] attribute. The framework automatically collects all such functions in your project and runs them.



Unit Tests



Unit tests are usually located in the same file as the code being tested, in a separate tests module. This allows testing private functions.



// src/lib.rspub fn add(a: i32, b: i32) -> i32 {    a + b}

fn private_helper(x: i32) -> i32 { x * 2}

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

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

#[test] fn test_private_helper() { assert_eq!(private_helper(5), 10); }}


Run: cargo test



Integration Tests



Integration tests are located in the tests/ directory at the project root level. Each file in this folder is a separate crate that tests your public API.



// tests/integration_test.rsuse my_crate::add;

#[test]fn test_add_integration() { assert_eq!(add(10, 20), 30);}


Assertion Macros



Rust provides several built-in macros for writing assertions:



  • assert!(expression) — panics if the expression is false.
  • assert_eq!(left, right) — checks equality using PartialEq.
  • assert_ne!(left, right) — checks inequality.
  • debug_assert!() — works only in debug builds.


#[test]fn test_with_assert() {    let result = some_function();    assert!(result.is_ok(), "Expected Ok, got: {:?}", result);    assert_eq!(result.unwrap(), 42);}


Doctests



One of Rust's most powerful features is the ability to write tests directly in the documentation. Code inside /// or //! blocks is automatically compiled and run as a test.



/// Adds two numbers.////// # Examples////// ```/// use my_crate::add;/// assert_eq!(add(1, 2), 3);/// ```pub fn add(a: i32, b: i32) -> i32 {    a + b}


Run: cargo test — doctests will run alongside regular tests.



Property-based Testing with proptest



The proptest library (analogous to Hypothesis in Python or QuickCheck in Haskell) allows you to generate random input data and check invariants.



use proptest::prelude::*;

fn reverse_string(s: &str) -> String { s.chars().rev().collect()}

proptest! { #[test] fn test_reverse_twice(s in ".*") { let reversed = reverse_string(&s); let double_reversed = reverse_string(&reversed); assert_eq!(s, double_reversed); }}


Installation: cargo add proptest



Benchmarks



For performance measurement in Rust, there are stable benchmarks (starting from Rust 1.78) via cargo bench and the criterion crate for more complex scenarios.



Built-in Benchmarks (nightly)



#![feature(test)]extern crate test;

#[bench]fn bench_add(b: &mut test::Bencher) { b.iter(|| add(1, 2));}


Benchmarks with criterion



Recommendations