測試 Rust 程式碼

本文說明編寫 Rust 程式碼測試的最佳做法。如需定義與執行測試套件和元件的操作說明,另請參閱元件測試指南

本文件的目標讀者為在 fuchsia.git 中工作的開發人員,而所述的工作流程可能不適用於 IDK 消費者。

您可以在 //examples/hello_world/rust 中找到本教學課程的原始碼。

單元測試

在程式碼中新增測試

新增 Rust 單元測試的慣用方法同樣也能在 Fuuchsia 中運作,而且要採用這個做法,只要在要編寫的測試底部執行以下程式碼片段,就能輕鬆完成:

#[cfg(test)]
mod tests {
    #[fuchsia::test]
    fn it_works() {
        assert_eq!(true, true);
    }
}

這項操作會建立名為 tests 的新模組,而且只有在建構單元測試時才會加入這個模組。任何加上 #[fuchsia::test] 註解的函式都會做為測試執行,如果函式成功傳回,則測試通過。

#[fuchsia::test] 也支援執行非同步程式碼的測試。

#[fuchsia::test]
async fn my_test() {
    let some_future = async { 4 };
    assert_eq!(some_future.await, 4);
}

一般 #[test] 註解也可以正常運作,但不支援非同步測試或立即登出功能。如果您認為 Crate 可能會用於 Fuchsia 程式碼集以外的地方,則建議使用 #[test]

建構測試

單元測試可由 Rust 目標 (例如 rustc_binaryrustc_library) 自動建構。方法相近且大。

為 Rust 二進位檔建構測試

本節適用於測試 Rust「二進位檔」 (也就是您有 main.rs)。如果使用的是程式庫,請參閱下一節。

BUILD.gn 檔案需要先匯入以提供 rustc_binary 範本才能使用:

import("//build/rust/rustc_binary.gni")

單元測試僅由 rustc_binary GN 範本建構,且只有在新增 with_unit_tests = true 設定時:

rustc_binary("bin") {
  name = "hello_world_rust"

  # Generates the "bin_test" build target
  with_unit_tests = true
  edition = "2021"

  deps = []
  test_deps = [ "//src/lib/fuchsia" ]

  sources = [ "src/main.rs" ]
}

設定 with_unit_tests = true 會讓這個建構規則產生兩個不同的執行檔,一個有提供項目,另一個有 _bin_test 附加至提供的名稱。

在此處的範例中,建立的執行檔名稱稱為:

  • hello_world_rust;以及
  • hello_world_rust_bin_test.

為 Rust 程式庫建構測試

BUILD.gn 檔案需要先匯入以提供 rustc_library 範本才能使用:

import("//build/rust/rustc_library.gni")

只有在新增 with_unit_tests = true 設定時,單元測試才會由 rustc_library GN 範本建構,與上述 rustc_binary 的情況類似。

但以下示例中,系統會建立「名稱不同」的測試二進位檔:

  • hello_world_rust_lib_test:請注意,二進位檔的名稱與程式庫產生的名稱不同。

二進位名稱在後續步驟中會使用,因此相當重要。

封裝及執行測試

如要執行先前目標產生的測試,請將這些目標封裝為測試元件您可以使用下列建構規則套件測試:

  • fuchsia_test_package():在單一套件中收集多個測試元件及其依附元件的套件範本。測試套件通常用於整合測試。
  • fuchsia_unittest_package():含有單元測試的套件專屬範本。單元測試套件可能會針對無必要功能的單元測試產生最小的元件資訊清單。

在 Hello World 二進位檔範例中,單元測試套件會參照產生的目標:bin_test (以目標名稱 bin 和隱性後置字串 _test 為基礎) 和 hello_world_rust_bin_test (以 name 段落的值為準)。

fuchsia_unittest_package("hello-world-rust-tests") {
  deps = [ ":bin_test" ]
}

如何執行測試:

fx test hello-world-rust-tests

如要瞭解如何封裝及執行測試,請參閱「測試元件」和「建構元件」。

實用的 Crate

下列樹狀結構內第三方 Crate 可協助您編寫測試:

  • assert_matches:提供 assert_matches! 巨集,使模式宣告符合人體工學。
  • pretty_assertions:提供替代的 assert_eq! 巨集,在斷言失敗時顯示顏色差異。

您可以在 BUILD.gntest_deps 下方找到這些項目。

rustc_binary("bin") {
  name = "my_test"
  with_unit_tests = true
  edition = "2021"

  test_deps = [
    "//third_party/rust_crates:matches",
    "//third_party/rust_crates:pretty_assertions",
  ]
}