請根據這個快速入門,根據簡易單元測試程式碼範例編寫驅動程式庫單元測試:
包含程式庫依附元件
包含此程式庫依附元件:
#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::DeviceServer
的 fdf_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* 函式 (RunInDriverContext
、RunInBackground
、RunInEnvironmentTypeContext
、RunInNodeContext
) 時請務必謹慎。由於這些工作會在特定調度工具上執行,因此可能不安全:
- 將原始指標從其他結構定義 (主執行緒或其他 Run* 種類) 傳遞至這些指標,以便用於函式
- 從擷取的拒絕或傳回類型中傳回原始指標,以便用於主執行緒,或在另一個 Run* 函式中擷取/使用 (相同類型的 Run* 函式除外)。