Testing in Rust
Rust ha un framework di testing integrato nel linguaggio. Non servono librerie esterne per scrivere ed eseguire test.
Test Unitari
I test unitari si scrivono nello stesso file del codice, in un modulo tests:
pub fn somma(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_somma() {
assert_eq!(somma(2, 3), 5);
}
#[test]
fn test_somma_negativi() {
assert_eq!(somma(-1, -1), -2);
}
}
Macro di Asserzione
#[test]
fn test_asserzioni() {
assert!(true); // Verifica booleano
assert_eq!(2 + 2, 4); // Verifica uguaglianza
assert_ne!(2 + 2, 5); // Verifica disuguaglianza
assert_eq!(2 + 2, 4, "La somma dovrebbe essere 4"); // Con messaggio
}
Test che Devono Causare Panic
#[test]
#[should_panic]
fn test_divisione_per_zero() {
dividi(10, 0);
}
#[test]
#[should_panic(expected = "divisione per zero")]
fn test_messaggio_panic() {
dividi(10, 0); // Verifica anche il messaggio del panic
}
Test con Result
#[test]
fn test_con_result() -> Result<(), String> {
let risultato = "42".parse::<i32>().map_err(|e| e.to_string())?;
if risultato == 42 {
Ok(())
} else {
Err(format!("Atteso 42, ottenuto {}", risultato))
}
}
Eseguire i Test
cargo test # Tutti i test
cargo test nome_test # Test specifico
cargo test test_somma # Test che contengono "test_somma"
cargo test -- --nocapture # Mostra println! durante i test
cargo test -- --test-threads=1 # Esegui test in sequenza
cargo test --doc # Solo doc-test
Ignorare Test
#[test]
#[ignore]
fn test_lento() {
// Test che richiede molto tempo
thread::sleep(Duration::from_secs(60));
}
cargo test -- --ignored # Esegue solo i test ignorati
cargo test -- --include-ignored # Esegue tutti, inclusi gli ignorati
Subtest con Naming
#[test]
fn test_validazione() {
let casi = vec![
("valido@email.com", true),
("invalido", false),
("", false),
];
for (email, atteso) in casi {
assert_eq!(
valida_email(email), atteso,
"Fallito per email: '{}'", email
);
}
}
Test di Integrazione
I test di integrazione vanno nella directory tests/:
progetto/
├── src/
│ └── lib.rs
└── tests/
└── integrazione.rs
// tests/integrazione.rs
use mio_progetto::somma;
#[test]
fn test_integrazione_somma() {
assert_eq!(somma(10, 20), 30);
}
Test Coverage
# Con cargo-tarpaulin
cargo install cargo-tarpaulin
cargo tarpaulin
Conclusione
Il framework di testing integrato in Rust rende semplice scrivere test affidabili senza dipendenze esterne. I test unitari vivono accanto al codice che testano grazie a #[cfg(test)], i test di integrazione nella directory tests/, e i doc-test garantiscono che la documentazione rimanga corretta. Esegui cargo test regolarmente per mantenere il codice solido.