Warum ist Codeabdeckung mehr als nur ein Häkchen in CI/CD?
\n\nStellen 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\nAber 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.
Warum sollte ein Rust-Entwickler die Abdeckung im Auge behalten?
\nRust 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
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\nWerkzeug Nr. 1: cargo-tarpaulin – Einfachheit und Geschwindigkeit
\ntarpaulin ist das beliebteste Werkzeug für die Codeabdeckung in Rust. Es funktioniert „out of the box“ und erfordert keine komplexe Einrichtung. Installation:
cargo install cargo-tarpaulin\nStarten einer Basisanalyse:
\ncargo tarpaulin --out Html\nDieser 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).
Beispiel: Testen einer einfachen Funktion
\nErstellen wir eine Datei src/lib.rs mit einer Funktion zur Berechnung der Fakultät:
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}\nStarten wir tarpaulin:
\ncargo tarpaulin --ignore-tests --out Html\nDas 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:
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}\nJetzt zeigt tarpaulin, dass der Zweig Err nicht durch Tests abgedeckt ist. Fügen wir einen Test hinzu:
#[test]\nfn test_negative() {\n assert!(factorial_safe(-5).is_err());\n}\nNach einem erneuten Durchlauf beträgt die Abdeckung wieder 100%.
\n\nErweiterte Einstellungen für tarpaulin
\nFü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
Werkzeug Nr. 2: grcov – Der König der Integrationen
\ngrcov ist ein flexibleres Werkzeug, das mit der LLVM-Toolchain arbeitet. Es ist besonders nützlich, wenn Sie CI/CD (GitHub Actions, GitLab