Testabdeckung in Rust: Von Null zu Sicherheit

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

Warum ist Codeabdeckung mehr als nur ein Häkchen in CI/CD?

\n\n

Stellen Sie sich vor: Sie haben in Rust ein Modul zum Parsen komplexer Konfigurationsdateien geschrieben. Der Compiler ist zufrieden, die Tests bestehen, aber einen Monat später stürzt die Produktion mit einem Fehler in einem seltenen Randfall ab. Kommt Ihnen das bekannt vor? Genau hier kommt die Testabdeckung in Rust ins Spiel – eine Metrik, die anzeigt, wie viel Prozent Ihres Codes während der Tests tatsächlich ausgeführt werden.

\n\n

Aber seien wir ehrlich: Die Jagd nach 100% Abdeckung ist eine Falle. Viel wichtiger ist es zu verstehen, welche Zeilen nicht getestet sind und warum. In diesem Artikel betrachten wir drei Hauptwerkzeuge für Rust: tarpaulin, grcov und die integrierte LLVM-Toolchain. Sie erfahren, wie Sie trockene Prozentsätze in umsetzbare Erkenntnisse für das Refactoring verwandeln.

\n\n

Warum sollte ein Rust-Entwickler die Abdeckung im Auge behalten?

\n

Rust ist bekannt für seine Speichersicherheit, aber das verhindert keine logischen Fehler. Die Testabdeckung hilft dabei:

\n
    \n
  • „Toten Code“ zu entdecken – Funktionen oder Verzweigungen, die nie aufgerufen werden.
  • \n
  • Das Vertrauen beim Refactoring zu stärken – im Wissen, dass kritische Pfade durch Tests abgedeckt sind.
  • \n
  • Die Dokumentation zu verbessern – Tests dienen oft als beste Dokumentation, wenn sie alle Szenarien abdecken.
  • \n
\n

Die wichtigste Metrik ist die Line Coverage (Zeilenabdeckung), aber wir werden uns auch die Branch Coverage (Zweigabdeckung) ansehen, die in Rust aufgrund der vielen match-Ausdrücke besonders wichtig ist.

\n\n

Werkzeug Nr. 1: cargo-tarpaulin – Einfachheit und Geschwindigkeit

\n

tarpaulin ist das beliebteste Werkzeug für die Codeabdeckung in Rust. Es funktioniert „out of the box“ und erfordert keine komplexe Einrichtung. Installation:

\n
cargo install cargo-tarpaulin
\n

Starten einer Basisanalyse:

\n
cargo tarpaulin --out Html
\n

Dieser Befehl generiert einen HTML-Bericht im Ordner tarpaulin-report.html. Öffnen wir ihn – und sehen eine Farbkarte Ihres Projekts: grüne Zeilen (durch Tests abgedeckt), rote (nicht abgedeckt) und graue (nicht ausführbar, z. B. Kommentare).

\n\n

Beispiel: Testen einer einfachen Funktion

\n

Erstellen wir eine Datei src/lib.rs mit einer Funktion zur Berechnung der Fakultät:

\n
pub fn factorial(n: u32) -> u32 {\n    match n {\n        0 | 1 => 1,\n        _ => n * factorial(n - 1),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_factorial() {\n        assert_eq!(factorial(0), 1);\n        assert_eq!(factorial(1), 1);\n        assert_eq!(factorial(5), 120);\n    }\n}
\n

Starten wir tarpaulin:

\n
cargo tarpaulin --ignore-tests --out Html
\n

Das Flag --ignore-tests schließt den Testcode selbst aus dem Bericht aus. Ergebnis: 100% Abdeckung für diese Funktion. Aber machen wir es etwas schwieriger – fügen wir eine Fehlerbehandlung hinzu:

\n
pub fn factorial_safe(n: i32) -> Result<u32, String> {\n    if n < 0 {\n        return Err("Negative Zahl!".to_string());\n    }\n    Ok(factorial(n as u32))\n}
\n

Jetzt zeigt tarpaulin, dass der Zweig Err nicht durch Tests abgedeckt ist. Fügen wir einen Test hinzu:

\n
#[test]\nfn test_negative() {\n    assert!(factorial_safe(-5).is_err());\n}
\n

Nach einem erneuten Durchlauf beträgt die Abdeckung wieder 100%.

\n\n

Erweiterte Einstellungen für tarpaulin

\n

Für größere Projekte verwenden Sie:

\n
    \n
  • --fail-under 80 – Abbruch mit Fehler, wenn die Abdeckung unter 80% liegt.
  • \n
  • --skip-clean – Projekt nicht neu erstellen, wenn die Änderungen geringfügig sind.
  • \n
  • --engine llvm – LLVM-Toolchain verwenden (experimentell, aber genauer).
  • \n
\n\n

Werkzeug Nr. 2: grcov – Der König der Integrationen

\n

grcov ist ein flexibleres Werkzeug, das mit der LLVM-Toolchain arbeitet. Es ist besonders nützlich, wenn Sie CI/CD (GitHub Actions, GitLab

Blogs

Buchempfehlungen