Tests
Rust ships its test runner with the language. #[test] functions live next to the code (unit tests in src/) or under tests/ for integration tests. cargo test discovers and runs them in parallel, captures stdout, and reports failures with full panic context. No framework, no config, no separate package.
Unit, integration, and doc tests with fixtures
EXAMPLE
// src/math.rs — production code + inline unit tests
pub fn add(a: i32, b: i32) -> i32 { a + b }
pub fn parse_positive(s: &str) -> Result<u32, &str> {
s.parse::<u32>().map_err(|_| "not a positive integer")
}
/// Returns true when n is a power of two.
///
/// ```
/// use mycrate::math::is_pow2;
/// assert!(is_pow2(64));
/// assert!(!is_pow2(0));
/// ```
pub fn is_pow2(n: u32) -> bool { n > 0 && n & (n - 1) == 0 }
// --- unit tests live in the same file, behind a cfg gate ---
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn add_works() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn parse_positive_rejects_negative() {
let err = parse_positive("-1").unwrap_err();
assert!(err.contains("positive"));
}
#[test]
#[should_panic(expected = "divide by zero")]
fn panics_as_expected() {
let _ = 1 / 0_i32;
}
#[test]
#[ignore = "slow — run with --ignored"]
fn big_input() { /* heavy computation */ }
// table-driven tests are just a loop with assert messages
#[test]
fn pow2_table() {
let cases = [(0u32, false), (1, true), (2, true), (3, false), (1024, true)];
for (n, expected) in cases {
assert_eq!(is_pow2(n), expected, "is_pow2({n}) wrong");
}
}
}
// tests/integration_orders.rs — uses the crate as an external user would
use mycrate::orders::{Order, place};
#[test]
fn place_assigns_id_and_total() {
let o = place(&[("apple", 2, 250), ("pear", 1, 300)]);
assert!(!o.id.is_empty());
assert_eq!(o.total_cents, 800);
}
// Run all tests: cargo test
// Run one: cargo test add_works
// Run including #[ignore]: cargo test -- --ignored
// Show captured println output: cargo test -- --nocapture
// Single-threaded (for shared global state): cargo test -- --test-threads=1
Why it matters
Doc tests run as part of cargo test, so the examples in your docs are guaranteed compilable and correct. That single mechanism kills the most common form of stale documentation in any language.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() { assert_eq!(2 + 2, 4); }
}
Try it Yourself »
Discussion
Loading…