本文將簡要介紹測試對應,並說明如何開始在 Android 開放原始碼專案 (AOSP) 中設定測試。
關於測試對應
測試對應是一種以 Gerrit 為基礎的方法,可讓開發人員直接在 Android 來源樹狀結構中建立提交前和提交後測試規則,並將要測試的分支和裝置的決定權交給測試基礎架構。測試對應定義是名為 TEST_MAPPING
的 JSON 檔案,可放置在任何來源目錄中。
Atest 可使用 TEST_MAPPING
檔案,在相關聯的目錄中執行提交前測試。透過測試對應,您可以在 Android 原始碼樹中進行最少變更,將相同的測試套組加入提交前檢查。
範例如下:
測試對應是以貿易聯盟 (TF) 測試控管工具執行測試和回報結果。
定義測試組
使用測試群組測試對應群組測試。測試群組的名稱可以是任何字串。舉例來說,presubmit 可以是驗證變更時要執行的一組測試的名稱。而「提交後」則是用於驗證變更合併後的版本。
套件建構指令碼規則
為了讓 Trade Federation 測試套件為特定版本執行測試模組,這些模組必須為 Soong 設定 test_suites
,或為 Make 設定 LOCAL_COMPATIBILITY_SUITE
,以便將其納入下列任一套件:
general-tests
適用於不依賴裝置特定功能 (例如大部分裝置都沒有的供應商專屬硬體) 的測試。大多數測試都應包含在general-tests
套件中,即使是特定 ABI、位元或硬體功能 (例如 HWASan) 也一樣 (每個 ABI 都有個別的test_suites
目標),即使必須在裝置上執行也一樣。device-tests
適用於依附裝置專屬功能的測試。通常這些測試會顯示在vendor/
下方。「裝置專屬」僅適用於「a」裝置專屬的功能,因此適用於 JUnit 測試和 GTest 測試 (即使只有 ABI 專屬,仍應標示為general-tests
)。
例如:
Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests
設定要在測試套件中執行的測試
如要在測試套件中執行測試,測試必須符合下列條件:
- 不得有任何建構提供者。
- 請務必在完成後清除所用資源,例如刪除測試期間產生的任何暫存檔案。
- 必須將系統設定變更為預設值或原始值。
不應假設裝置處於特定狀態,例如可進行 Root 作業。大多數測試不需要 Root 權限即可執行。如果測試必須要求使用 root,則應在其
AndroidTest.xml
中使用RootTargetPreparer
指定,如以下範例所示:<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
建立測試對應檔案
針對需要測試涵蓋率的目錄,請新增類似於範例的 TEST_MAPPING
JSON 檔案。這些規則可確保在該目錄或任何子目錄中觸及任何檔案時,測試會在提交前檢查中執行。
參考範例
以下是 TEST_MAPPING
檔案範例 (採用 JSON 格式,但支援註解):
{
"presubmit": [
// JUnit test with options and file patterns.
{
"name": "CtsWindowManagerDeviceTestCases",
"options": [
{
"include-annotation": "android.platform.test.annotations.RequiresDevice"
}
],
"file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
},
// Device-side GTest with options.
{
"name" : "hello_world_test",
"options": [
{
"native-test-flag": "\"servicename1 servicename2\""
},
{
"native-test-timeout": "6000"
}
]
}
// Host-side GTest.
{
"name" : "net_test_avrcp",
"host" : true
}
],
"postsubmit": [
{
"name": "CtsDeqpTestCases",
"options": [
{
// Use regex in include-filter which is supported in AndroidJUnitTest
"include-filter": "dEQP-EGL.functional.color_clears.*"
}
]
}
],
"imports": [
{
"path": "frameworks/base/services/core/java/com/android/server/am"
}
]
}
設定屬性
在範例中,presubmit
和 postsubmit
是各個測試群組的名稱。如要進一步瞭解測試群組,請參閱「定義測試群組」。
您可以在 name
屬性的值中,設定測試模組名稱或 Trade Federation 整合測試名稱 (測試 XML 檔案的資源路徑,例如 uiautomator/uiautomator-demo
)。請注意,name
欄位無法使用類別 name
或測試方法 name
。如要縮小要執行的測試範圍,請使用 include-filter
等選項。請參閱 include-filter
使用範例。
測試的 host
設定會指出測試是否為在主機上執行的無裝置測試。預設值為 false
,表示測試需要裝置才能執行。支援的測試類型包括 GTest 二進位檔的 HostGTest
,以及 JUnit 測試的 HostTest
。
file_patterns
屬性可讓您設定規則運算式字串清單,用於比對任何原始碼檔案的相對路徑 (相對於包含 TEST_MAPPING
檔案的目錄)。在範例中,只有在 Java 檔案以 Window
或 Activity
開頭,且位於 TEST_MAPPING
檔案或其任何子目錄所在的目錄時,測試 CtsWindowManagerDeviceTestCases
才會在提交前執行。反斜線 (\) 位於 JSON 檔案中,因此需要轉義。
imports
屬性可讓您在其他 TEST_MAPPING
檔案中加入測試,而無須複製內容。匯入路徑上層目錄中的 TEST_MAPPING
檔案也會一併匯入。測試對應可讓您進行巢狀匯入;也就是說,有兩個 TEST_MAPPING
檔案可以互相匯入,而測試對應可以合併內含的測試。
options
屬性包含其他 Tradefed 指令列選項。
如要取得特定測試的可用選項完整清單,請執行以下指令:
tradefed.sh run commandAndExit [test_module] --help
如要進一步瞭解選項的運作方式,請參閱「交易的選項處理」。
使用 Atest 執行測試
如何在本機執行提交前測試規則:
- 前往包含
TEST_MAPPING
檔案的目錄。 執行下列指令:
atest
系統會執行目前目錄及其上層目錄的 TEST_MAPPING
檔案中設定的所有提交前測試。Atest 會找出並執行兩項預提交測試 (A 和 B)。
這是在目前工作目錄 (CWD) 和父目錄中的 TEST_MAPPING
檔案中執行提交前測試最直接的方式。Atest 會在 CWD 及其所有父目錄中尋找並使用 TEST_MAPPING
檔案。
結構化原始碼
以下範例說明如何在來源樹狀結構中設定 TEST_MAPPING
檔案:
src
├── project_1
│ └── TEST_MAPPING
├── project_2
│ └── TEST_MAPPING
└── TEST_MAPPING
src/TEST_MAPPING
的內容:
{
"presubmit": [
{
"name": "A"
}
]
}
src/project_1/TEST_MAPPING
的內容:
{
"presubmit": [
{
"name": "B"
}
],
"postsubmit": [
{
"name": "C"
}
],
"other_group": [
{
"name": "X"
}
]}
src/project_2/TEST_MAPPING
的內容:
{
"presubmit": [
{
"name": "D"
}
],
"import": [
{
"path": "src/project_1"
}
]}
指定目標目錄
您可以指定目標目錄,以便在該目錄中的 TEST_MAPPING
檔案中執行測試。下列指令會執行兩項測試 (A、B):
atest --test-mapping src/project_1
執行提交後測試規則
您也可以使用這個指令,在 src_path
(預設為 CWD) 和其父目錄中,執行 TEST_MAPPING
中定義的提交後測試規則:
atest [--test-mapping] [src_path]:postsubmit
只執行不需要裝置的測試
您可以使用 Atest 的 --host
選項,只執行針對主機設定的測試,而不需要裝置。如果不使用此選項,Atest 會執行兩個測試 (要求的裝置和在無需裝置的主機上執行的測試)。測試會在兩個獨立的套件中執行:
atest [--test-mapping] --host
找出測試組
您可以在 Atest 指令中指定測試群組。以下指令會執行 src/project_1
目錄中與檔案相關的所有 postsubmit
測試,該目錄只包含一個測試 (C)。
或者,您也可以使用 :all
執行所有測試,不分群組。下列指令會執行四項測試 (A、B、C、X):
atest --test-mapping src/project_1:all
包含子目錄
根據預設,使用 Atest 在 TEST_MAPPING
中執行的測試,只會執行 CWD (或指定目錄) 和其上層目錄中 TEST_MAPPING
檔案中設定的預提交測試。如果您想在子目錄中的所有 TEST_MAPPING
檔案中執行測試,請使用 --include-subdir
選項,強制 Atest 也納入這些測試。
atest --include-subdir
如果沒有 --include-subdir
選項,Atest 只會執行測試 A。使用 --include-subdir
選項時,Atest 會執行兩項測試 (A、B)。
支援行層級註解
您可以新增逐行 //
格式註解,以便進一步說明 TEST_MAPPING
檔案,並說明後續的設定。ATest 和貿易聯盟預先處理 TEST_MAPPING
為有效的 JSON 格式,不含任何註解。為保持 JSON 檔案的清晰,系統僅支援行級 //
格式註解。
例子:
{
// For presubmit test group.
"presubmit": [
{
// Run test on module A.
"name": "A"
}
]
}