Grundlagen des Softwaretestens in Rust

RustRustBeginner
Jetzt üben

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

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab werden wir die Wichtigkeit des Testens bei der Softwareentwicklung mit Rust untersuchen und lernen, verschiedene Arten von Tests wie Unit-Tests und Integrationstests zu schreiben. Wir werden auch lernen, wie man Tests in Rust-Projekten organisiert und mithilfe des Befehls cargo test ausführt. Darüber hinaus werden wir die potenziellen Probleme diskutieren, die bei der parallelen Ausführung von Tests auftreten können, und geben ein Beispiel, um dies zu veranschaulichen.

Hinweis: Wenn das Lab keinen Dateinamen angibt, können Sie einen beliebigen Dateinamen verwenden. Beispielsweise können Sie main.rs verwenden, es mit rustc main.rs &&./main kompilieren und ausführen.

Testen

Wir wissen, dass das Testen für jedes Softwarestück unverzichtbar ist! Rust bietet eine erstklassige Unterstützung für Unit- und Integrationstests (siehe dieses Kapitel in der TRPL).

Aus den verlinkten Testkapiteln oben sehen wir, wie man Unit- und Integrationstests schreibt. Organisationell können wir Unit-Tests in den Modulen platzieren, die sie testen, und Integrationstests im eigenen tests/-Verzeichnis:

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

Jede Datei in tests ist ein separater Integrationstest, d.h. ein Test, der das Ziel hat, Ihre Bibliothek so zu testen, als würde sie von einem abhängigen Crate aufgerufen werden.

Das Testkapitel geht auf die drei verschiedenen Teststile ein: Unit, Doc und Integration.

cargo bietet natürlich einen einfachen Weg, alle Ihre Tests auszuführen!

$ cargo test

Sie sollten eine Ausgabe wie diese sehen:

[object Object]

Sie können auch Tests ausführen, deren Name einem Muster entspricht:

$ cargo test test_foo
[object Object]

Ein Wort der Vorsicht: Cargo kann mehrere Tests gleichzeitig ausführen, also stellen Sie sicher, dass sie nicht miteinander konkurrieren.

Ein Beispiel dafür, dass diese Konkurrenz zu Problemen führt, ist, wenn zwei Tests in eine Datei schreiben, wie unten:

#[cfg(test)]
mod tests {
    // Importiere die erforderlichen Module
    use std::fs::OpenOptions;
    use std::io::Write;

    // Dieser Test schreibt in eine Datei
    #[test]
    fn test_file() {
        // Öffnet die Datei ferris.txt oder erstellt sie, wenn sie nicht existiert.
        let mut file = OpenOptions::new()
         .append(true)
         .create(true)
         .open("ferris.txt")
         .expect("Fehler beim Öffnen von ferris.txt");

        // Druckt "Ferris" 5 Mal.
        for _ in 0..5 {
            file.write_all("Ferris\n".as_bytes())
             .expect("Konnte nicht in ferris.txt schreiben");
        }
    }

    // Dieser Test versucht, in die gleiche Datei zu schreiben
    #[test]
    fn test_file_also() {
        // Öffnet die Datei ferris.txt oder erstellt sie, wenn sie nicht existiert.
        let mut file = OpenOptions::new()
         .append(true)
         .create(true)
         .open("ferris.txt")
         .expect("Fehler beim Öffnen von ferris.txt");

        // Druckt "Corro" 5 Mal.
        for _ in 0..5 {
            file.write_all("Corro\n".as_bytes())
             .expect("Konnte nicht in ferris.txt schreiben");
        }
    }
}

Obwohl der Zweck darin besteht, Folgendes zu erhalten:

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

Was tatsächlich in ferris.txt geschrieben wird, ist dies:

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

Zusammenfassung

Herzlichen Glückwunsch! Sie haben das Testen-Lab abgeschlossen. Sie können in LabEx weitere Labs absolvieren, um Ihre Fähigkeiten zu verbessern.