Fondamentaux des tests logiciels en Rust

RustRustBeginner
Pratiquer maintenant

This tutorial is from open-source community. Access the source code

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, nous explorerons l'importance des tests dans le développement logiciel en utilisant Rust et apprendrons à écrire différents types de tests tels que les tests unitaires et les tests d'intégration. Nous apprendrons également à organiser les tests dans les projets Rust et à les exécuter en utilisant la commande cargo test. De plus, nous discuterons des problèmes potentiels qui peuvent survenir lors de l'exécution concurrente de tests et fournirons un exemple pour illustrer cela.

Note : Si le laboratoire ne spécifie pas de nom de fichier, vous pouvez utiliser n'importe quel nom de fichier que vous voulez. Par exemple, vous pouvez utiliser main.rs, le compiler et l'exécuter avec rustc main.rs &&./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/ControlStructuresGroup(["Control Structures"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/BasicConceptsGroup -.-> rust/mutable_variables("Mutable Variables") rust/DataTypesGroup -.-> rust/boolean_type("Boolean Type") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/ControlStructuresGroup -.-> rust/for_loop("for Loop") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") subgraph Lab Skills rust/variable_declarations -.-> lab-99339{{"Fondamentaux des tests logiciels en Rust"}} rust/mutable_variables -.-> lab-99339{{"Fondamentaux des tests logiciels en Rust"}} rust/boolean_type -.-> lab-99339{{"Fondamentaux des tests logiciels en Rust"}} rust/string_type -.-> lab-99339{{"Fondamentaux des tests logiciels en Rust"}} rust/for_loop -.-> lab-99339{{"Fondamentaux des tests logiciels en Rust"}} rust/function_syntax -.-> lab-99339{{"Fondamentaux des tests logiciels en Rust"}} rust/expressions_statements -.-> lab-99339{{"Fondamentaux des tests logiciels en Rust"}} rust/lifetime_specifiers -.-> lab-99339{{"Fondamentaux des tests logiciels en Rust"}} rust/method_syntax -.-> lab-99339{{"Fondamentaux des tests logiciels en Rust"}} end

Tests

Comme nous le savons, les tests sont essentiels pour tout logiciel! Rust offre un support de première classe pour les tests unitaires et d'intégration (voir ce chapitre dans le TRPL).

Dans les chapitres sur les tests liés ci-dessus, nous voyons comment écrire des tests unitaires et des tests d'intégration. Sur le plan organisationnel, nous pouvons placer les tests unitaires dans les modules qu'ils testent et les tests d'intégration dans leur propre répertoire tests/ :

foo
├── Cargo.toml
├── src
│   └── main.rs
│   └── lib.rs
└── tests
    ├── my_test.rs
    └── my_other_test.rs

Chaque fichier dans tests est un test d'intégration distinct, c'est-à-dire un test destiné à tester votre bibliothèque comme si elle était appelée à partir d'une crate dépendante.

Le chapitre sur les tests détaile les trois styles de tests différents : Unitaires, Doc et d'Intégration.

cargo fournit naturellement un moyen simple d'exécuter tous vos tests!

$ cargo test

Vous devriez voir une sortie comme celle-ci :

[object Object]

Vous pouvez également exécuter les tests dont le nom correspond à un motif :

$ cargo test test_foo
[object Object]

Un mot d'avertissement : Cargo peut exécuter plusieurs tests en parallèle, assurez-vous donc qu'ils ne se chevauchent pas.

Un exemple de problèmes causés par cette concurrence est si deux tests écrivent dans un fichier, comme ci-dessous :

#[cfg(test)]
mod tests {
    // Importe les modules nécessaires
    use std::fs::OpenOptions;
    use std::io::Write;

    // Ce test écrit dans un fichier
    #[test]
    fn test_file() {
        // Ouvre le fichier ferris.txt ou le crée s'il n'existe pas.
        let mut file = OpenOptions::new()
         .append(true)
         .create(true)
         .open("ferris.txt")
         .expect("Impossible d'ouvrir ferris.txt");

        // Affiche "Ferris" 5 fois.
        for _ in 0..5 {
            file.write_all("Ferris\n".as_bytes())
             .expect("Impossible d'écrire dans ferris.txt");
        }
    }

    // Ce test essaie d'écrire dans le même fichier
    #[test]
    fn test_file_also() {
        // Ouvre le fichier ferris.txt ou le crée s'il n'existe pas.
        let mut file = OpenOptions::new()
         .append(true)
         .create(true)
         .open("ferris.txt")
         .expect("Impossible d'ouvrir ferris.txt");

        // Affiche "Corro" 5 fois.
        for _ in 0..5 {
            file.write_all("Corro\n".as_bytes())
             .expect("Impossible d'écrire dans ferris.txt");
        }
    }
}

Bien que l'intention soit d'obtenir ceci :

$ cat ferris.txt
Ferris
Ferris
Ferris
Ferris
Ferris
Corro
Corro
Corro
Corro
Corro

Voici ce qui est effectivement écrit dans ferris.txt :

$ cargo test test_foo
Corro
Ferris
Corro
Ferris
Corro
Ferris
Corro
Ferris
Corro
Ferris

Résumé

Félicitations! Vous avez terminé le laboratoire sur les Tests. Vous pouvez pratiquer d'autres laboratoires dans LabEx pour améliorer vos compétences.