assert_eq! și assert_ne! în Rust

Macro-uri de verificare și panică Rust 1.0 (assert_ne!: 1.13)

Verifică dacă două valori sunt egale (assert_eq!) sau diferite (assert_ne!); la eșec, panica afișează ambele valori.

Sintaxă
assert_eq!(stanga, dreapta);
assert_eq!(stanga, dreapta, "mesaj {}", x);
assert_ne!(stanga, dreapta);

Ce face assert_eq! și assert_ne!

assert_eq!(a, b) verifică a == b. Dacă nu sunt egale, dă panică cu un mesaj care arată ambele valori: left: ... (primul argument) și right: ... (al doilea). assert_ne!(a, b) verifică a != b. Sunt verificările folosite cel mai des în teste.

Valorile trebuie să implementeze PartialEq (pentru comparare) și Debug (pentru afișare la eșec), deci structurile proprii au nevoie de #[derive(Debug, PartialEq)]. După valori poți da un mesaj propriu, cu sintaxa lui format!.

Prin convenție, mulți pun valoarea calculată în stânga și pe cea așteptată în dreapta, dar Rust nu impune ordinea. Ca și assert!, rămân active în release; există și debug_assert_eq!/debug_assert_ne!.

Exemple

Exemplul 1: Verificări care trec

Se compară numere, texte, vectori și structuri proprii (cu Debug și PartialEq derivate).

#[derive(Debug, PartialEq)]
struct Punct {
    x: i32,
    y: i32,
}

fn mijloc(a: &Punct, b: &Punct) -> Punct {
    Punct { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 }
}

fn main() {
    assert_eq!(2 + 2, 4);
    assert_eq!("Iași".to_uppercase(), "IAȘI");
    assert_eq!(vec![3, 1, 2].iter().max(), Some(&3));
    assert_eq!(mijloc(&Punct { x: 0, y: 0 }, &Punct { x: 10, y: 4 }), Punct { x: 5, y: 2 });
    assert_ne!("Ana", "ana");
    println!("Toate verificările au trecut");
}

Rezultat

Toate verificările au trecut

Exemplul 2: O verificare care eșuează

Funcția numără greșit cuvintele (ignoră ultimul). Mesajul arată valoarea obținută (left), cea așteptată (right) și mesajul propriu.

fn numara_cuvinte(text: &str) -> usize {
    text.matches(' ').count()
}

fn main() {
    let text = "Rust este un limbaj rapid";
    assert_eq!(numara_cuvinte(text), 5, "textul: {text:?}");
    println!("ok");
}

Rezultat (programul se oprește cu panică)

thread 'main' (14810126) panicked at main.rs:7:5:
assertion `left == right` failed: textul: "Rust este un limbaj rapid"
  left: 4
 right: 5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Greșeli frecvente

  • Compari valori cu virgulă calculate: assert_eq!(0.1 + 0.2, 0.3) eșuează (rezultatul este 0.30000000000000004). Compară cu o toleranță: assert!((a - b).abs() < 1e-9).
  • Compari o structură fără #[derive(Debug)]: `Punct` doesn't implement `Debug`, chiar dacă are PartialEq.
  • Compari tipuri diferite: assert_eq!(s, "text") merge pentru String și &str, dar assert_eq!(n, 5u8) cu n: i32 nu se compilează.

Comenzi înrudite

  • assert! și debug_assert!: Verifică o condiție la rulare și dă panică dacă este falsă. debug_assert! face verificarea doar în modul debug, nu și în release.
  • teste (#[test]): O funcție marcată cu #[test] este un test automat: cargo test o rulează și raportează dacă a trecut sau a dat panică.
  • cargo test: Compilează proiectul în mod test și rulează toate testele: cele #[test], testele din tests/ și exemplele din documentație.
  • panic!: Oprește firul de execuție curent cu un mesaj de eroare. Se folosește pentru situații care nu ar trebui să apară niciodată (bug-uri).