Fuchsia 測試執行者架構

Fuchsia 元件架構可讓開發人員在 選擇多種語言和執行階段Fuchsia 自己的程式碼採用各式各樣的 包括 C/C++、Rust、Dart 和 Go 等元件的程式設計語言。

測試執行器架構會使用元件架構執行器做為 各種測試執行階段與常見的 Fuchsia 通訊協定整合層 來推出測試及接收結果這讓音樂的包容性 方便開發人員單憑一臂之力 另一方面,建構及測試 Fuchsia 並指定不同的硬體

測試經理

test_manager 元件負責在 Fuchsia 上執行測試 裝置。測試管理員會公開 fuchsia.test.manager.RunBuilder 通訊協定, 發布測試套件

每個測試套件都會以測試管理員的子項的形式推出。提供測試套件 建立一套完整功能 以便保持測試與系統的其他部分之間例如 鑑識測試得到記錄訊息的能力,但沒有針對 能夠與沙箱外的實際系統資源互動 測試管理員只使用測試領域中的一項能力,也就是控制器通訊協定 公開測試套件這是為了確保確認性 (測試結果不會 在預期沙箱之外的任何內容) 和隔離 (測試) 並不會影響彼此或系統其餘部分)。

測試管理員控制器本身會提供給系統中的其他元件 ,將測試執行作業與各種開發人員工具整合。測試 並透過 fx testffx 等工具啟動。

測試套件通訊協定

測試套件通訊協定 fuchsia.test.Suite 是由 以便控制測試,例如叫用測試案例 也就是預測結果

測試作者通常不需要實作這個通訊協定。相反地 方法是使用測試執行器。舉例來說,您可以將 使用 GoogleTest 架構以 C++ 編寫測試,然後使用 元件資訊清單中的 gtest_runner 以便與測試執行器架構整合

測試執行工具

涵蓋語言與執行階段的架構

測試執行器是測試執行器架構與常用轉接器 語言與以及開發人員撰寫測試時使用的架構這些範本會導入 fuchsia.test.Suite 通訊協定,代表測試作者 讓開發人員為自家的語言和架構編寫慣用的測試 就是用哪一種烤箱或刀子都可以 那麼預先建構的容器或許是最佳選擇

產生簡易單元測試的元件資訊清單 取代為建構規則為第 2 版測試產生的元件資訊清單會包含 根據建構定義找出適合的測試執行元件。例如測試 而依附於 GoogleTest 程式庫的執行檔,則會納入 所產生資訊清單中的 GoogleTest 執行器

測試執行工具目錄

下列測試執行器目前可供一般用途:

GoogleTest 執行元件

使用 GoogleTest 架構以 C/C++ 編寫測試的執行器。 請將此方法用於所有透過 GoogleTest 編寫的測試。

支援一般 GoogleTest 功能,例如停用測試、執行 例如指定測試、重複執行同一項測試等等。 從測試中擷取標準輸出內容、標準錯誤和記錄。

如要使用這個執行元件,請將以下內容新增至元件資訊清單:

{
    include: [ "//src/sys/test_runners/gtest/default.shard.cml" ]
}

根據預設,GoogleTest 測試案例會依序執行 (一次一個測試案例)。

GoogleTest (Gunit) 執行元件

使用 GUnit 架構以 C/C++ 編寫測試的執行器。 所有使用 GoogleTest 的 gUnit 變種版本編寫的測試都使用這個屬性。

支援一般 GoogleTest 功能,例如停用測試、執行 例如指定測試、重複執行同一項測試等等。 從測試中擷取標準輸出內容、標準錯誤和記錄。

如要使用這個執行元件,請將以下內容新增至元件資訊清單:

{
    include: [ "sys/testing/gunit_runner.shard.cml" ]
}

根據預設,系統會依序執行測試案例 (一次一個測試案例)。

Rust 執行元件

使用 Rust 程式設計語言編寫的測試執行器,接著在 Rust 之後 以及測試慣用語 這適用於所有慣用的 Rust 測試 (例如使用設有 屬性 [cfg(test)])。

支援常見的 Rust 測試功能,例如停用測試、執行 例如指定測試、重複執行同一項測試等等。 從測試中擷取標準輸出內容、標準錯誤和記錄。

如要使用這個執行元件,請將以下內容新增至元件資訊清單:

{
    include: [ "//src/sys/test_runners/rust/default.shard.cml" ]
}

根據預設,Rust 測試案例會平行執行,一次最多 10 個案例。

Go 測試執行元件

以 Go 程式設計語言編寫且在 Go 之後編寫的測試執行器 以及測試慣用語 這適用於所有使用 import "testing" 編寫的 Go 測試。

支援一般 Go 測試功能,例如停用測試、執行 例如指定測試、重複執行同一項測試等等。 從測試中擷取標準輸出內容、標準錯誤和記錄。

如要使用這個執行元件,請將以下內容新增至元件資訊清單:

{
    include: [ "//src/sys/test_runners/gotests/default.shard.cml" ]
}

根據預設,Go 測試案例會同時執行,一次最多 10 個案例。

ELF 測試執行元件

最簡單的測試執行元件,它會等待程式終止,然後再回報 如果該程式傳回 0 或失敗 非零的回傳值。

如果測試是以 ELF 程式的形式實作,請使用這個測試執行元件 (例如 以 C/C++ 編寫的執行檔),但不使用一般的測試架構 可以擴充現有的執行器,而您不想依照個人需求 測試執行元件

如要使用這個執行元件,請將以下內容新增至元件資訊清單:

{
    include: [ "sys/testing/elf_test_runner.shard.cml" ]
}

如果你樹狀結構內單元測試 GN 範本, 而且您尚未搭配專用測試執行元件使用測試架構。 將以下內容新增到建構依附元件:

fuchsia_unittest_package("my-test-packkage") {
    // ...
    deps = [
        // ...
        "//src/sys/testing/elftest",
    ]
}

控管測試案例的平行執行作業

使用 fx test 啟動測試時,可能會依序執行每個測試案例,或 可同時執行多個測試案例,直到達到指定上限為止。預設 平行處理行為是由測試執行元件決定。如要手動控制 要平行使用的測試規格執行的測試案例數量:

fuchsia_test_package("my-test-pkg") {
  test_components = [ ":my_test_component" ]
  test_specs = {
    # control the parallelism
    parallel = 10
  }
}

多次執行測試

如要多次執行測試,請使用:

 fx test --count=<n> <test_url>

如果疊代逾時,系統就不會執行進一步的疊代作業。

傳送引數

您可以使用 fx test 為測試傳遞自訂引數:

fx test <test_url> -- <custom_args>

個別測試執行器對以下自訂標記設有限制:

GoogleTest 執行元件

請注意以下已知的行為變更:

--gtest_break_on_failure - 請改用:

fx test --break-on-failure <test_url>

下列旗標受到限制,如果系統將其中任一旗標做為傳遞狀態,測試就會失敗 fuchsia.test.Suite 提供相同功能來取代原有功能。

  • --gtest_filter - 請改用:
 fx test --test-filter=<glob_pattern> <test_url>

--test-filter 可以多次指定。符合以下任一項目的測試 指定的 glob 模式

  • --gtest_also_run_disabled_tests - 請改用:
 fx test --also-run-disabled-tests <test_url>
  • --gtest_repeat - 請參閱多次執行測試
  • --gtest_output - 不支援略過 gtest JSON 輸出。
  • --gtest_list_tests - 不支援列出測試案例。

GoogleTest (Gunit) 執行元件

請注意以下已知的行為變更:

--gunit_break_on_failure - 請改用:

fx test --break-on-failure <test_url>

下列旗標受到限制,如果系統將其中任一旗標做為傳遞狀態,測試就會失敗 fuchsia.test.Suite 提供相同功能來取代原有功能。

  • --gunit_filter - 請改用:
 fx test --test-filter=<glob_pattern> <test_url>

--test-filter 可以多次指定。符合以下任一項目的測試 指定的 glob 模式

  • --gunit_also_run_disabled_tests - 請改用:
 fx test --also-run-disabled-tests <test_url>
  • --gunit_repeat - 請參閱多次執行測試
  • --gunit_output - 不支援略過 gtest json/xml 輸出。
  • --gunit_list_tests - 不支援列出測試案例。

Rust 執行元件

下列旗標受到限制,如果系統將其中任一旗標做為傳遞狀態,測試就會失敗 fuchsia.test.Suite 提供相同功能來取代原有功能。

  • &lt;test_name_matcher&gt; - 請改用:
 fx test --test-filter=<glob_pattern> <test_url>

--test-filter 可以多次指定。符合以下任一項目的測試 指定的 glob 模式

  • --nocapture - 根據預設會顯示輸出內容。
  • --list - 不支援列出測試案例。

Go 測試執行元件

請注意以下已知的行為變更:

-test.failfast:由於每個測試案例都會在不同的程序中執行,因此這個 只會影響子測試

下列旗標受到限制,如果系統將其中任一旗標做為傳遞狀態,測試就會失敗 fuchsia.test.Suite 提供相同功能來取代他們

  • -test.run - 請改用:
 fx test --test-filter=<glob_pattern> <test_url>

--test-filter 可以多次指定。符合以下任一項目的測試 指定的 glob 模式

跨執行階段的各執行階段測試架構

Fuchsia 的目標是展現多元包容精神 開發人員可使用慣用的語言和執行階段建立元件 (以及測試) 測試執行器架構本身適用於各語言模型 專精於特定程式設計語言或測試 因此也就在於語言包容性任何人都能建立及使用新的 測試執行工具

建立新的測試執行器相對簡單,而且可能會共用 在不同執行器之間來回切換例如 GoogleTest 執行元件和 Rust 執行元件會共用與啟動 ELF 二進位檔相關的程式碼,但不同 將指令列引數傳遞至測試並剖析測試結果。

暫時儲存空間

如要在測試中使用暫存儲存空間,請將以下內容新增至元件資訊清單:

{
    include: [ "//src/sys/test_runners/tmp_storage.shard.cml" ]
}

在執行階段,您的測試將擁有 /tmp 的讀取/寫入權限。 測試開始時,這個目錄的內容將是空的, 。

測試未指定自訂資訊清單的測試,並改為 依賴建構系統產生元件資訊清單 下列依附元件:

fuchsia_unittest_package("foo-tests") {
  deps = [
    ":foo_test",
    "//src/sys/test_runners:tmp_storage",
  ]
}

匯出自訂檔案

如要從測試中匯出自訂檔案,請使用 custom_artifacts 儲存空間 技術。系統會在最後複製 custom_artifacts 的內容 。

如要在測試中使用 custom_artifacts,請將以下內容新增至元件 資訊清單:

{
    use: [
        {
            storage: "custom_artifacts",
            rights: [ "rw*" ],
            path: "/custom_artifacts",
        },
    ],
}

在執行階段,您的測試將擁有 /custom_artifacts 的讀取/寫入權限。 測試開始時,這個目錄的內容將是空的, 。

請參閱自訂構件測試範例。如要執行,請新增 //examples/tests/rust:tests 傳送至您的建構,然後執行:

fx test --ffx-output-directory <output-dir> custom_artifact_user

測試結束後,<output-dir> 會包含 artifact.txt 檔案 。

Hermeticity

在軟體測試中,「歷史性」是指 從外部因素和依附元件到測試或測試套件 無論 YAML 檔案 周圍環境。密封檢測屬於獨立性質,且不依賴 外部系統或資料可能會意外變動 非確定性的測試結果

Hermeticity 不代表必須享有穩定平台所提供的保護, 這些功能/API如果 API 介面在某些元件中必須穩定 系統建構版本,就會是測試和相依元件的穩定版 協助捕捉任何直接或直接變更系統 API 造成的迴歸 途徑。

Fuchsia 的「測試 超能力測試語意有兩種:

  • 功能:測試不會使用優惠 測試根目錄父項中的所有功能。這些測試 可以使用任何可能影響較大系統的系統功能。因為 平行測試的本質測試屬性可以平行執行 因此改善了以下項目的穩定性和效能: 測試。

  • 套件:測試不會解析 測試套件。傳統封裝測試沒有任何隱含合約 進行測試這樣一來,您就能在不影響 系統套件,避免依賴不相容的封裝依附元件。

密封設定不適用於可用於 系統中的所有元件例如

  • clock
  • 核心提供的 ID,例如 koids。
  • 所有元件均提供架構功能,方便客戶 變更元件管理員狀態,雖然這並不算是純粹 但元件管理員的責任

這類測試在使用這些 API/功能時應謹慎測試。

除非另有明確說明,否則測試預設為密封。

用於測試的密封功能

所有測試都能使用某些功能,但不會違反政策 隱性:

通訊協定 說明
fuchsia.boot.WriteOnlyLog 寫入核心記錄
fuchsia.logger.LogSink 寫入 Syslog
fuchsia.process.Launcher 從測試套件啟動子項程序
fuchsia.diagnostics.ArchiveAccessor 讀取測試中各元件的診斷輸出內容

這些技能的特性是一體適用的,因此能保留特徵 不允許測試影響測試以外的系統元件行為 測試領域。

如要使用這些功能,請在測試的 資訊清單檔案:

// my_test.cml
{
    use: [
        ...
        {
            protocol: [
              "fuchsia.logger.LogSink"
            ],
        },
    ],
}

測試也提供部分預設儲存功能 已刪除。

儲存功能 說明 路徑
data 獨立資料儲存空間目錄 /data
cache 隔離的快取儲存空間目錄 /cache
tmp 記憶體內暫存儲存空間目錄 /tmp

在測試的資訊清單檔案中新增使用宣告,即可使用這些功能。

// my_test.cml
{
    use: [
        ...
        {
            storage: "data",
            path: "/data",
        },
    ],
}

這個架構也為全體客戶提供了一些功能 並可供測試元件使用 (如有需要)。

密封元件解析度

在採用密封的領域中啟動密封測試元件 元件解析器此解析器不允許解析 測試套件這是強制執行隱密性的必要步驟 您是否希望系統上或 變更測試結果

如果嘗試解析未納入測試套件的元件,將會得到 PackageNotFound 錯誤和 Syslog 中的以下訊息:

failed to resolve component fuchsia-pkg://fuchsia.com/[package_name]#meta/[component_name]: package [package_name] is not in the set of allowed packages...

如要避免這個錯誤,請加入測試依賴的任何元件 發布至測試套件,請參閱這個 CL 範例, 實作方式,或使用子套件

# BUILD.gn
import("//build/components.gni")


fuchsia_test_package("simple_test") {
  test_components = [ ":simple_test_component" ]
  subpackages = [ "//path/to/subpackage:subpackage" ]
}
 // test.cml
 {
...
    children: [
        {
            name: "child",
            url: "subpackage#meta/subpackaged_component.cm",
        },
    ],
...
}

如需使用子套件的範例,請參閱這個 CL

// my_component_test.cml

{
...

    facets: {
        "fuchsia.test": {
            "deprecated-allowed-packages": [ "non_hermetic_package" ],
        },
    },
...
}

非密封測試

這些測試可以存取測試領域以外的部分預先定義功能。 由測試領域以外的非密封測試所存取的功能稱為 系統功能

如要使用系統能力,測試必須明確標示要在測試中執行 非密封的領域,如下所示

# BUILD.gn (in-tree build rule)

fuchsia_test_component("my_test_component") {
  component_name = "my_test"
  manifest = "meta/my_test.cml"
  deps = [ ":my_test_bin" ]

  # This runs the test in "system-tests" non-hermetic realm.
  test_type = "system"
}

與建構規則整合後,測試即可以下列形式執行:

fx test <my_test>

或者適用於樹狀結構外開發人員

ffx test run --realm <realm_moniker> <test_url>

其中 realm_moniker 應替換為 /core/testing:system-tests

test_type 可能的值:

說明
chromium Chromium 測試運作範圍
ctf CTF 測試運作範圍
device 裝置測試
drm DRM 測試
starnix Starnix 挑戰賽
system_validation 系統驗證測試
system 具備部分系統功能存取權的舊版非密封運作範圍
test_arch 測試架構測試
vfs-compliance VFS 法規遵循測試
vulkan Vulkan 測試

瞭解如何建立自己的測試領域。

非密封的舊版測試運作範圍

這些是舊版測試領域 測試管理員即服務。我們正在處理 才能轉移這些領域如果測試需要使用其中一項運作範圍,則應 明確將其標示為在舊版運作領域中執行,如下所示。

// my_component_test.cml

{
    include: [
        // Select the appropriate test runner shard here:
        // rust, gtest, go, etc.
        "//src/sys/test_runners/rust/default.shard.cml",

        // This includes the facet which marks the test type as 'starnix'.
        "//src/devices/testing/starnix_test.shard.cml",
    ],
    program: {
        binary: "bin/my_component_test",
    },
    
    use: [
        {
            protocol: [ "fuchsia.vulkan.loader.Loader" ],
        },
    ],
}

這個資料分割的資訊清單檔案中包含下列 facet:

// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
{
    include: [ "//src/starnix/tests/starnix_test_common.shard.cml" ],
    expose: [
        {
            protocol: "fuchsia.test.Suite",
            from: "self",
        },
    ],
}

fuchsia.test.type 可能的值:

說明
hermetic 遺傳領域
chromium-system Chromium 系統測試運作領域
google Google 測試領域

受限記錄檔

根據預設,測試會記錄的嚴重性為「 ERROR 以上版本。詳情請參閱這份指南

成效

編寫啟動程序的測試執行元件時,執行元件需 提供了程式庫載入器實作程序。

測試執行器通常會在不同的程序中啟動個別測試案例, 就能享有更大的測試案例不過, 大幅降低效能成本為緩解這個情況,系統已列出下列測試執行器 使用快取載入器服務,降低 每項程序啟動時都會產生額外負擔

測試角色

測試領域中的元件在測試中可能扮演不同的角色,如下所示:

  • 測試根目錄:測試元件樹狀結構頂端的元件。網址 測試會找出這個元件,測試管理員則會叫用 此元件公開的 fuchsia.test.Suite, 進行測試
  • 測試驅動程式:實際執行測試 (直接或透過測試執行器fuchsia.test.Suite 通訊協定。請注意 驅動程式庫和測試根目錄不一定相同,但不一定是相同的元件: 測試驅動程式庫可能是測試根目錄的子元件,用於重新公開 例如 fuchsia.test.Suite
  • 功能提供者:提供測試能力的元件 應該可以運動元件可能會提供「假」 測試能力的實作,或稱「真實」 相當於正式環境
  • 受測試的元件:會練習特定行為的元件。 可能與實際工作環境中的元件或編寫的元件相同 。

疑難排解

本節包含開發測試元件時可能遇到的常見問題 測試執行工具架構如果其中一個測試元件無法執行,您可能會看到 來自 fx test 的錯誤:

Test suite encountered error trying to run tests: getting test cases
Caused by:
    The test protocol was closed. This may mean `fuchsia.test.Suite` was not configured correctly.

如要解決這個問題,請參考下列做法:

測試使用的測試執行元件有誤

如果在測試列舉期間遇到這個錯誤,那麼您 用錯誤的測試執行元件

舉例來說,Rust 測試檔案可能會在 進行測試,而不使用 Rust 測試架構 (即是一種簡單的 Rust 二進位檔, 各自的主函式)。在這種情況下,請將測試資訊清單檔案變更為 elf_test_runner

進一步瞭解內建的測試執行器

測試無法將 fuchsia.test.Suite 公開給測試管理員

當測試根目錄沒有公開 fuchsia.test.Suite 的 「test root」。簡單的修正方式是新增 expose 宣告:

// test_root.cml
expose: [
    ...
    {
        protocol: "fuchsia.test.Suite",
        from: "self",  // If a child component is the test driver, put `from: "#driver"`
    },
],

測試驅動程式庫無法向根層級公開 fuchsia.test.Suite

如果 fuchsia.test.Suite,測試可能會失敗,並顯示類似下列的錯誤 未正確公開通訊協定:

ERROR: Failed to route protocol `/svc/fuchsia.test.Suite` from component
`/test_manager/...`: An `expose from #driver` declaration was found at `/test_manager/...`
for `/svc/fuchsia.test.Suite`, but no matching `expose` declaration was found in the child

如果測試驅動程式庫和測試根不同,就是測試驅動程式庫 也必須向父項 (測試根層級) 公開 fuchsia.test.Suite

如要解決這個問題,請確認「測試驅動程式」元件資訊清單包含以下內容: 下列 expose 宣告:

// test_driver.cml
expose: [
    ...
    {
        protocol: "fuchsia.test.Suite",
        from: "self",
    },
],

測試驅動程式庫不使用測試執行元件

測試驅動程式必須使用適當的測試執行器 或是對應測試時所用的語言和測試架構。 舉例來說,Rust 測試的驅動程式庫需要下列宣告:

// test_driver.cml
include: [ "//src/sys/test_runners/rust/default.shard.cml" ]

此外,如果測試驅動程式庫是測試根子項,請 提供給驅動程式庫參考:

// test_root.cml
offer: [
    {
        runner: "rust_test_runner",
        to: [ "#driver" ],
    },
],

其他資訊

  • 複雜拓撲與整合測試:測試 獨立於多個元件之間的互動 有些人會將 Cloud Storage 視為檔案系統 但實際上不是