Testing — #[test], cargo test, and Doctests
Jest → cargo test
Section titled “Jest → cargo test”In TypeScript you reach for Jest (or Vitest) and write describe/it/expect blocks in separate .test.ts files. Rust’s test runner is built into the compiler: annotate any function with #[test] and cargo test will discover and run it automatically — no third-party crate required.
Unit tests live next to the code
Section titled “Unit tests live next to the code”// math.tsexport function add(a: number, b: number): number { return a + b;}
// math.test.tsimport { add } from './math';test('adds two numbers', () => { expect(add(3, 4)).toBe(7);});// src/lib.rs (tests live in the same file)pub fn add(a: i32, b: i32) -> i32 { a + b}
#[cfg(test)]mod tests { use super::*; // import everything from the parent module
#[test] fn test_add() { assert_eq!(add(3, 4), 7); }
#[test] fn test_add_negative() { assert_eq!(add(-1, 1), 0); }}The #[cfg(test)] attribute means the test module is only compiled when running cargo test — it is stripped from release builds automatically.
Running tests
Section titled “Running tests”cargo test # run all tests in the projectcargo test test_add # run tests whose name contains "test_add"cargo test -- --nocapture # show println! output during testscargo test -- --test-threads=1 # run tests sequentially (no parallelism)Common assertion macros
Section titled “Common assertion macros”assert_eq!(left, right); // expect(a).toBe(b)assert_ne!(left, right); // expect(a).not.toBe(b)assert!(condition); // expect(condition).toBeTruthy()assert!(condition, "message {}", 42); // with a custom failure messageExpecting a panic (like Jest’s toThrow)
Section titled “Expecting a panic (like Jest’s toThrow)”#[test]#[should_panic(expected = "divide by zero")]fn test_divide_by_zero() { divide(10, 0); // this function should panic}Doctests — tests inside doc comments
Section titled “Doctests — tests inside doc comments”Rust can run code examples written in /// doc comments. They serve as both documentation and tests.
/// Adds two integers together.////// # Examples////// ```/// let result = my_crate::add(2, 3);/// assert_eq!(result, 5);/// ```pub fn add(a: i32, b: i32) -> i32 { a + b}Run them with the same command: cargo test.
Playground note:
#[test]functions require thecargo testbinary context and cannot run in the browser playground. The snippet below usesfn mainwithassert_eq!to demonstrate the same logic — runcargo testlocally for the full test suite experience.
Try it — logic under test
Section titled “Try it — logic under test”fn add(a: i32, b: i32) -> i32 { a + b}
fn is_even(n: i32) -> bool { n % 2 == 0}
fn main() { // Manually exercise the logic (in real projects, use #[test]) assert_eq!(add(3, 4), 7); assert_eq!(add(-1, 1), 0); assert!(is_even(4)); assert!(!is_even(7)); println!("All assertions passed!");}Compiling…