proptest für Rust: Komplette Anleitung mit Beispielen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

proptest für Rust: Vollständige Anleitung zum Property-Based Testing

1. Was ist proptest und warum wird es benötigt?

Die Bibliothek proptest ist ein leistungsstarkes Framework für property-based Testing (eigenschaftsbasiertes Testen) in der Programmiersprache Rust. Im Gegensatz zum traditionellen Unit-Testing, bei dem Sie manuell konkrete Eingabedaten und erwartete Ergebnisse vorgeben, geht das property-based Testing einen anderen Weg: Sie beschreiben Eigenschaften (Invarianten), die für alle gültigen Eingabedaten gelten müssen. Die Bibliothek generiert daraufhin automatisch eine Vielzahl zufälliger Testfälle und prüft, ob die angegebene Eigenschaft verletzt wird.

Warum ist das sinnvoll? Erstens hilft es dabei, "Randfälle" (edge cases) zu finden, an die der Entwickler vielleicht gar nicht gedacht hat: leere Zeichenketten, negative Zahlen, extrem große Werte oder null-ähnliche Zustände. Zweitens sind property-basierte Tests selbstdokumentierend: Sie beschreiben den Vertrag einer Funktion ("für jede Zahl x gibt die Funktion f(x) eine Zahl größer als 0 zurück") und nicht nur ein einzelnes Beispiel. Drittens bleiben solche Tests bei Code-Änderungen oft ohne Anpassungen gültig, da sie allgemeine Eigenschaften und keine konkreten Werte prüfen.

proptest ist das Rust-Pendant zu Bibliotheken wie QuickCheck (Haskell), Hypothesis (Python) und FsCheck (.NET). Es bietet eine umfangreiche Sammlung von Strategien zur Datengenerierung (von einfachen Zahlen bis zu komplexen Strukturen), einen Mechanismus zur Schrumpfung (Shrinking) zur Minimierung fehlschlagender Beispiele und eine nahtlose Integration in das Haupt-Testframework von Rust: cargo test.

2. Installation

Um proptest zu verwenden, fügen Sie es im Abschnitt [dev-dependencies] Ihrer Cargo.toml-Datei hinzu:

[dev-dependencies]
proptest = "1.4"

Führen Sie anschließend folgenden Befehl aus:

cargo build

Die Bibliothek wird heruntergeladen und kompiliert. Jetzt können Sie sie in Ihren Testmodulen verwenden.

3. Schnellstart – Ein minimales funktionierendes Beispiel

Schreiben wir einen einfachen Test, der prüft, ob die Funktion reverse (Zeichenkette umkehren) eine Involution ist: Wenn man sie zweimal anwendet, erhält man die ursprüngliche Zeichenkette zurück.

// src/lib.rs
pub fn reverse(s: &str) -> String {
    s.chars().rev().collect()
}

#[cfg(test)]
mod tests {
    use super::*;
    use proptest::prelude::*;

    proptest! {
        #[test]
        fn test_reverse_involution(s in ".*") {
            let reversed = reverse(&s);
            let double_reversed = reverse(&reversed);
            assert_eq!(s, double_reversed);
        }
    }
}

Starten Sie den Test mit cargo test. proptest generiert 256 zufällige Zeichenketten (Standardeinstellung) und prüft, ob die Eigenschaft erfüllt ist. Sollte der Test fehlschlagen, versucht die Bibliothek, ein minimales Beispiel zu finden, das den Fehler reproduziert.

4. Wichtige Methoden und Funktionen

Im Folgenden werden die wichtigsten Komponenten der Bibliothek proptest vorgestellt. Alle Beispiele gehen davon aus, dass am Anfang des Testmoduls use proptest::prelude::*; eingefügt wurde.

4.1. Das Makro proptest!

Signatur: proptest! { ... }

Funktion: Das Hauptmakro, das einen Block für property-basierte Tests definiert. Innerhalb dieses Blocks können Testfunktionen mit automatischer Datengenerierung deklariert werden.

proptest! {
    #[test]
    fn test_addition_commutative(a in 0..100i32, b in 0..100i32) {
        assert_eq!(a + b, b + a);
    }
}

4.2. Die Strategie any::<T>()

Empfehlungen