Loading...
Loading...

Rust Unit Testing

Unit testing in Rust is a first-class feature with built-in test framework support. Tests verify individual units of code in isolation, helping catch bugs early and document expected behavior. Rust's compiler guarantees test safety with no runtime overhead.

1. Writing and Running Tests

Test Functions: Annotated with #[test], containing assertions.

// In src/lib.rs or a tests/ module
#[cfg(test)] // Compile only when testing
mod tests {
    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }

    #[test]
    #[should_panic(expected = "divide by zero")]
    fn test_panic() {
        divide(10, 0); // Should panic
    }
}

// Run tests with:
// cargo test

Key Commands:

  • cargo test - Runs all tests
  • cargo test test_name - Runs specific test
  • cargo test -- --ignored - Runs only ignored tests

2. Test Organization

Module Structure: Tests can live alongside code or in separate files.

// Option 1: Inline tests module
#[cfg(test)]
mod tests {
    use super::*; // Import parent module items
    
    #[test]
    fn test_add() {
        assert_eq!(add(2, 2), 4);
    }
}

// Option 2: External test file
// tests/integration_test.rs
use my_crate::add;

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

Test Types:

  • Unit tests: Test individual functions/modules (src/)
  • Integration tests: Test public API (tests/ directory)
  • Doc tests: Code examples in documentation

3. Assertion Macros

Verification Tools: Rust provides several assertion macros.

#[test]
fn test_assertions() {
    // Equality
    assert_eq!(2 + 2, 4);
    assert_ne!(3, 4);

    // Boolean conditions
    assert!(result.is_ok());
    assert!(!value.is_empty());

    // Custom failure messages
    assert!(
        user.is_admin(),
        "User {} is not admin",
        user.name
    );

    // Approximate floating point comparisons
    assert_approx_eq!(0.1 + 0.2, 0.3, 1e-10);
}

Common Macros:

  • assert! - Boolean condition
  • assert_eq!/assert_ne! - Equality checks
  • assert_matches! - Pattern matching
  • #[should_panic] - Expected failures

4. Test Fixtures

Reusable Setup: Common initialization patterns.

// Setup function
fn setup_test_data() -> Vec<i32> {
    vec![1, 2, 3]
}

#[test]
fn test_with_fixture() {
    let data = setup_test_data();
    assert_eq!(data.len(), 3);
}

// Test-specific modules
mod database_tests {
    struct TestDatabase {
        conn: DatabaseConnection,
    }

    impl TestDatabase {
        fn new() -> Self {
            // Set up test database
        }
    }

    #[test]
    fn test_query() {
        let db = TestDatabase::new();
        // Test with fresh instance
    }
}

Advanced Patterns:

  • Drop implementations for cleanup
  • Lazy static initialization
  • Mocking with trait objects

5. Advanced Test Features

Special Test Cases: Rust supports various test scenarios.

// 1. Ignored tests
#[test]
#[ignore = "Too slow for CI"]
fn expensive_test() {
    // Long-running test
}

// 2. Test return values
#[test]
fn test_result() -> Result<(), String> {
    if 2 + 2 == 4 {
        Ok(())
    } else {
        Err(String::from("Math is broken"))
    }
}

// 3. Benchmark tests (nightly only)
#[bench]
fn bench_sort(b: &mut test::Bencher) {
    let mut v = vec![0; 10000];
    b.iter(|| v.sort());
}

Test Flags:

  • --nocapture - Show output from passing tests
  • --test-threads=1 - Run tests sequentially
  • --include-ignored - Run all tests including ignored

6. Property-Based Testing

Generate Test Cases: Verify behavior across many inputs.

use proptest::prelude::*;

proptest! {
    #[test]
    fn test_addition_commutative(a: i32, b: i32) {
        assert_eq!(a + b, b + a);
    }

    #[test]
    fn test_string_concat(s in ".*", sub in ".*") {
        let combined = format!("{}{}", s, sub);
        assert!(combined.contains(&s));
        assert!(combined.contains(&sub));
    }
}

Property Test Crates:

  • proptest - General property testing
  • quickcheck - Haskell-style testing
  • rstest - Parameterized tests
0 Interaction
0 Views
Views
0 Likes
×
×
×
🍪 CookieConsent@Ptutorials:~

Welcome to Ptutorials

$ Allow cookies on this site ? (y/n)

top-home