Introduction aux tests en Rust
Rust est un langage de programmation système réputé pour sa sécurité et ses performances. Cependant, même le code le plus fiable a besoin d'être vérifié. Les tests en Rust ne sont pas simplement une option, mais une partie intégrante du processus de développement. Grâce au support intégré des tests dans Cargo, vous pouvez facilement écrire et exécuter des tests unitaires, d'intégration et e2e. Dans cet article, nous allons explorer ces trois niveaux de tests avec des exemples pratiques.
Tests unitaires en Rust : le fondement de la fiabilité
Les tests unitaires vérifient des fonctions et méthodes individuelles de manière isolée. En Rust, ils sont généralement placés directement dans le fichier de code, dans un module spécial tests.
Structure d'un test unitaire
Chaque test unitaire est une fonction marquée par l'attribut #[test]. À l'intérieur, vous utilisez les macros assert!, assert_eq! et assert_ne! pour vérifier les résultats.
// src/math.rspub fn add(a: i32, b: i32) -> i32 { a + b}
pub fn divide(a: f64, b: f64) -> Result<f64, String> { if b == 0.0 { Err(String::from("Division par zéro")) } else { Ok(a / b) }}
#[cfg(test)]mod tests { use super::*;
#[test] fn test_add() { assert_eq!(add(2, 3), 5); }
#[test] fn test_divide_success() { let result = divide(10.0, 2.0); assert!(result.is_ok()); assert_eq!(result.unwrap(), 5.0); }
#[test] fn test_divide_by_zero() { let result = divide(10.0, 0.0); assert!(result.is_err()); assert_eq!(result.unwrap_err(), "Division par zéro"); }}Notez l'attribut #[cfg(test)]. Il indique au compilateur d'inclure ce module uniquement lors de la compilation des tests. Cela permet d'économiser du temps de compilation pour le binaire final.
Exécution des tests unitaires
Pour exécuter tous les tests du projet, utilisez la commande :
cargo testVous pouvez également exécuter un test spécifique par son nom :
cargo test test_addOu filtrer les tests par mot-clé :
cargo test divideTests d'intégration en Rust : vérification des interactions
Les tests d'intégration vérifient comment les différents modules de votre application fonctionnent ensemble. Contrairement aux tests unitaires, ils se trouvent dans un dossier séparé tests/ à la racine du projet.
Structure d'un test d'intégration
Créez un fichier tests/integration_test.rs :
// tests/integration_test.rsuse my_project::math; // supposons que la bibliothèque s'appelle my_project
#[test]fn test_add_and_divide() { let sum = math::add(10, 5); let result = math::divide(sum as f64, 3.0).unwrap(); assert_eq!(result, 5.0);}
#[test]fn test_complex_calculation() { let a = math::add(100, 200); let b = math::add(50, 50); let result = math::divide(a as f64, b as f64).unwrap(); assert_eq!(result, 3.0);}Chaque fichier dans tests/ est compilé comme une crate séparée. Cela signifie que vous pouvez avoir plusieurs fichiers de tests pour différents scénarios.
Module commun pour les tests d'intégration
Si vous avez besoin d'utilitaires communs pour tous les tests d'intégration, créez un sous-dossier tests/common/ avec un fichier mod.rs :
// tests/common/mod.rspub fn setup() { // Initialisation de l'environnement de test println!("Mise en place de l'environnement de test...");}Et utilisez-le dans les tests :
// tests/integration_test.rsmod common;
#[test]fn test_with_setup() { common::setup(); // Votre test}Tests E2E en Rust : immersion complète
Les tests E2E (end-to-end) vérifient le fonctionnement de l'ensemble de l'application du début à la fin. En Rust, des outils externes sont souvent utilisés pour cela.