駕駛組測試快速入門

請根據這個快速入門,根據簡易單元測試程式碼範例編寫驅動程式庫單元測試:

包含程式庫依附元件

包含此程式庫依附元件:

#include <lib/driver/testing/cpp/fixtures/gtest_fixture.h>

DriverTestFixture 是驅動程式庫單元測試固件類別可以繼承的基本類別。測試會定義設定類別,以便透過範本參數傳入固件。固件會負責在正確的調度工具上設定測試環境和驅動程式庫,並依要求啟動和停止驅動程式庫。

建立固件設定類別

DriverTestFixture 基礎類別會透過範本參數納入設定類別。這項設定類別必須提供特定值,以指定測試的執行方式。

以下是設定類別的範例:

class FixtureConfig final {
 public:
  static constexpr bool kDriverOnForeground = true;
  static constexpr bool kAutoStartDriver = true;
  static constexpr bool kAutoStopDriver = true;

  using DriverType = simple::SimpleDriver;
  using EnvironmentType = SimpleDriverTestEnvironment;
};

定義環境類型類別

EnvironmentType 必須是獨立的類別,可提供驅動程式的自訂依附元件。不需要提供架構依附元件 (compat::DeviceServer 除外),因為已有該韌體的固件。如果不需要其他依附元件,請使用提供預設 compat::DeviceServerfdf_testing::MinimalEnvironment

以下是精簡環境的基本測試範例:

#include <lib/driver/testing/cpp/fixtures/gtest_fixture.h>

class FixtureConfig final {
 public:
  static constexpr bool kDriverOnForeground = true;
  static constexpr bool kAutoStartDriver = true;
  static constexpr bool kAutoStopDriver = true;

  using DriverType = MyDriverType;
  using EnvironmentType = fdf_testing::MinimalEnvironment;
};

class MyFixture : public fdf_testing::DriverTestFixture<FixtureConfiguration> {};

TEST_F(MyFixture, MyTest) {
  driver().DoSomething();
}

執行單元測試

驅動程式單元測試是在驅動程式庫本身的測試資料夾中執行。舉例來說,請執行下列指令,執行 iwlwifi 驅動程式庫的驅動程式庫測試:

tools/bazel test third_party/iwlwifi/test:iwlwifi_test_pkg

DriverTestFixture 設定引數

DriverType

受測試的驅動程式庫類型。這必須是 fdf::DriverBase 的繼承者。

使用 DriverType 僅為固件函式 (例如 driver()RunInDriverContext()) 定義參照類型。使用驅動程式庫註冊符號 (由 FUCHSIA_DRIVER_EXPORT 巨集建立) 進行驅動程式庫生命週期管理。使用自訂驅動程式庫類型時,請確認自訂 DriverType 包含具有以下簽名的公開靜態函式:

static DriverRegistration GetDriverRegistration()

測試時會使用該註冊作業管理驅動程式庫生命週期。

EnvironmentType

包含受測試驅動程式庫自訂依附元件的類別。環境一律會在背景調度器上運作。

這個名稱必須預設為可建構,衍生自 fdf_testing::Environment class,並覆寫下列函式: zx::result<> Serve(fdf::OutgoingDirectory& to_driver_vfs) override;

在初始化期間,系統會在背景環境調度工具自動呼叫該函式。必須將元件新增至提供的 fdf::OutgoingDirectory object,通常透過 AddService 方法完成。OutgoingDirectory 會傳回驅動程式庫傳入的命名空間,因此其名稱 to_driver_vfs

自訂環境範例:

class MyFidlServer : public fidl::WireServer<fuchsia_examples_gizmo::Proto> {...};

class CustomEnvironment : public fdf_testing::Environment {
 public:
  zx::result<> Serve(fdf::OutgoingDirectory& to_driver_vfs) {
    device_server_.Init(component::kDefaultInstance, "root");
    EXPECT_EQ(ZX_OK, device_server_.Serve(
    fdf::Dispatcher::GetCurrent()->async_dispatcher(), &to_driver_vfs));

    EXPECT_EQ(ZX_OK, to_driver_vfs.AddService<fuchsia_examples_gizmo::Service::Proto>(
      custom_server_.CreateInstanceHandler()).status_value());

    return zx::ok();
  }

 private:
  compat::DeviceServer device_server_;
 MyFidlServer custom_server_;
};

kDriverOnForeground (偏好為 = true)

要讓受測試的驅動程式庫在前景調度工具上執行,或是在專屬的背景調度工具上執行。

如果為 true,測試可以使用 driver() 方法存取接受測試的驅動程式庫,並直接呼叫其,但同步處理用戶端工作必須通過 RunInBackground()

當此情況為 false 時,測試可以使用 RunInDriverContext() 方法,在驅動程式庫內容上執行工作,但同步處理用戶端工作可以直接執行。

kAutoStartDriver (偏好 = true)

如果為 true,測試將會在建構 DriverTestFixture 時自動啟動驅動程式庫,並預期啟動成功。

kAutoStopDriver (偏好 = true)

如果為 true,測試將自動停止驅動程式庫刪除 DriverTestFixture,並預期成功停止。

在所有設定中可用於測試的方法

下列方法可透過所有設定進行測試。

播放時長

存取驅動程式庫執行階段物件。這可用來建立新的背景調度器,或執行前景調度工具。使用者不需要為環境或驅動程式庫明確建立調度工具,因為韌體已經完成了。

連線

連線至受測試驅動程式庫程式提供的服務成員執行個體。這可以是驅動程式庫運輸服務,也可以是司康管道運輸服務。

ConnectThroughDevfs

連線至驅動程式庫透過 devfs 匯出的通訊協定。為此,您可以將 devfs 節點的 node_name 提供給,或在到達 devfs 節點之前,將要周遊的節點名稱清單提供給我們。

RunInEnvironmentTypeContext

這個外掛程式能在測試使用的 EnvironmentType 執行個體上執行工作。

RunInNodeContext

在測試使用的 fdf_testing::TestNode 執行個體上執行工作。可用於驗證驅動程式與驅動程式庫程式架構節點的互動,例如檢查已新增的子項數量。

透過設定限制的測試方法

有特定設定限制 (在括號內) 可使用下列方法進行測試。

StartDriver 和 StartDriverCustomized (kAutoStartDriver = false)

這可用來手動啟動測試中的驅動程式庫。只有在 kAutoStartDriver 為 False 時才能使用。自訂變化版本可用來修改提供給驅動程式庫的起始引數。

StopDriver (kAutoStopDriver = false)

可用來手動停止接受測試的驅動程式庫。只有在 kAutoStopDriver 為 False 時才能使用。

RunInDriverContext (kDriverOnForeground = false)

這可用於在受測試的驅動程式庫上執行回呼。回呼輸入會取得驅動程式庫的參照。根據這項設定,在主要測試執行緒上接觸驅動程式庫並不安全,因此所有驅動程式庫的存取權都必須經過這個步驟。

驅動程式庫 (kDriverOnForeground = true)

可用來直接從測試存取驅動程式庫。由於驅動程式庫位於前景,因此可以透過主要測試執行緒安全存取這個項目。

RunInBackground (kDriverOnForeground = true)

在背景調度器 (與驅動程式庫分開) 上執行工作。這樣做可以避免在使用 kDriverOnForeground 設定執行同步用戶端呼叫時,驅動程式庫發生死結。

執行* 函式警告

使用 Run* 函式 (RunInDriverContextRunInBackgroundRunInEnvironmentTypeContextRunInNodeContext) 時請務必謹慎。由於這些工作會在特定調度工具上執行,因此可能不安全:

  • 將原始指標從其他結構定義 (主執行緒或其他 Run* 種類) 傳遞至這些指標,以便用於函式
  • 從擷取的拒絕或傳回類型中傳回原始指標,以便用於主執行緒,或在另一個 Run* 函式中擷取/使用 (相同類型的 Run* 函式除外)。

範例