Rust's built-in testing framework makes it easy to ensure your code works as expected. Let's explore the three main types of tests in Rust: unit tests, integration tests, and benchmarks.
Unit Tests
Unit tests in Rust are typically small, focused tests that verify the behavior of a single function or module. They're written in the same file as the code they're testing.
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
fn add(a: i32, b: i32) -> i32 {
a + b
}
Key points:
- Use the
#[cfg(test)]
attribute to compile test code only when running tests. - Each test function is annotated with
#[test]
. - Use assertion macros like
assert_eq!
to verify results.
Integration Tests
Integration tests verify that different parts of your library work together correctly. They're located in the tests
directory at the root of your project.
// In tests/integration_test.rs
use yourcrate_name;
#[test]
fn test_complex_operation() {
let result = yourcrate_name::complex_operation();
assert!(result.is_ok());
}
Key points:
- Each file in the
tests
directory is compiled as a separate crate. - They can only test the public API of your library.
- Run with
cargo test
.
Benchmarks
Benchmarks help you measure the performance of your code. They're unstable in Rust and require the nightly toolchain.
#![feature(test)]
extern crate test;
#[cfg(test)]
mod bench {
use test::Bencher;
use super::*;
#[bench]
fn bench_add(b: &mut Bencher) {
b.iter(|| add(2, 2));
}
}
Key points:
- Use
#![feature(test)]
to enable benchmarking. - Annotate benchmark functions with
#[bench]
. - Run with
cargo bench
.
Remember that writing tests is crucial for maintaining code quality and catching bugs early. Rust's testing framework makes it straightforward to create comprehensive test suites for your projects.