測試映射

這是對測試映射的簡要介紹,並解釋瞭如何在 Android 開源項目 (AOSP) 中輕鬆開始配置測試。

什麼是測試映射?

測試映射是一種基於 Gerrit 的方法,它允許開發人員直接在 Android 源代碼樹中創建提交前和提交後的測試規則,並將要測試的分支和設備的決定留給測試基礎設施本身。測試映射定義是名為 TEST_MAPPING 的 JSON 文件,可以放置在任何源目錄中。

Atest可以使用 TEST_MAPPING 文件在相關目錄中運行預提交測試。使用測試映射,您可以通過在 Android 源代碼樹中進行簡單更改來添加相同的測試集以進行預提交檢查。

請參閱以下示例:

將 presubmit 測試添加到 services.core 的 TEST_MAPPING

使用導入為工具/dexter 添加預提交測試到 TEST_MAPPING

測試映射依賴於貿易聯盟 (TF) 測試工具來執行測試和報告結果。

定義測試組

測試映射通過測試組對測試進行分組。測試組的名稱可以是任何字符串。例如,預提交可以是在驗證更改時運行一組測試。提交後測試可用於在合併更改後驗證構建。

打包構建腳本規則

為了讓Trade Federation 測試工具為給定的構建運行 Test Mapping 的測試模塊,這些模塊必須將test_suite設置為Soong或將LOCAL_COMPATIBILITY_SUITE設置為 Make 到以下兩個套件之一:

  • general-tests - 不依賴於特定設備功能的測試(例如大多數設備沒有的特定於供應商的硬件)。大多數測試應該在通用測試套件中,即使它們特定於一個 ABI 或位或硬件功能,如 HWASan(每個 ABI 都有一個單獨的 test_suites 目標),即使它們必須在設備上運行。
  • device-tests - 依賴於設備特定功能的測試。通常這些測試將在vendor/下找到。因為“特定於設備”並不指其他設備可能具有或不具有的 ABI 或 SoC 功能,而僅指設備獨有功能,所以這適用於 JUnit 測試的每一點與 GTest 原生測試(通常應該是general-tests ,即使它們是特定於 ABI 的)。

例子:

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": "CtsWindowManagerDeviceTestCases"
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

設置屬性

在上面的示例中, presubmitpostsubmit是每個測試組的名稱。有關測試組的更多信息,請參閱定義測試組。

可以在name屬性的值中設置測試模塊nameTrade Federation 集成測試名稱(測試 XML 文件的資源路徑,例如uiautomator/uiautomator-demo )。注意名稱字段不能使用類name或測試方法name 。要縮小要運行的測試範圍,您可以在此處使用include-filter等選項。請參閱(包含過濾器示例用法)。

測試的主機設置指示測試是否是在主機上運行的無設備測試。默認值為false ,表示測試需要設備才能運行。支持的測試類型是用於GTest二進製文件的HostGTest和用於 JUnit 測試的 HostTest。

file_patterns屬性允許您設置正則表達式字符串列表以匹配任何源代碼文件的相對路徑(相對於包含 TEST_MAPPING 文件的目錄)。在上面的例子中,測試CtsWindowManagerDeviceTestCases將在 presubmit 中運行,只有當任何以 Window 或 Activity 開頭的 java 文件存在於 TEST_MAPPING 文件或其任何子目錄的同一目錄中被更改時。反斜杠 \ 需要轉義,因為它們在 JSON 文件中。

導入屬性允許您在其他 TEST_MAPPING 文件中包含測試,而無需複制內容。請注意,導入路徑的父目錄中的 TEST_MAPPING 文件也將包括在內。測試映射允許嵌套導入;這意味著兩個 TEST_MAPPING 文件可以相互導入,並且測試映射能夠正確合併包含的測試。

options屬性包含額外的 TradeFed 命令行選項。

要獲取給定測試的可用選項的完整列表,請運行:

tradefed.sh run commandAndExit [test_module] --help

有關期權如何運作的更多詳細信息,請參閱TradeFed 期權處理

使用 Atest 運行測試

要在本地執行預提交測試規則:

  1. 轉到包含 TEST_MAPPING 文件的目錄。
  2. 運行命令:
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 中的文件相關的所有提交後測試,該目錄僅包含一個測試 (C)。

或者您可以使用:all運行所有測試,而不管組。以下命令運行四個測試(A、B、C、X):

atest --test-mapping src/project_1:all

包括子目錄

默認情況下,使用 Atest 在 TEST_MAPPING 中運行測試將僅運行在 CWD(或給定目錄)及其父目錄中的 TEST_MAPPING 文件中配置的提交前測試。如果要在子目錄中的所有 TEST_MAPPING 文件中運行測試,請使用選項 --include --include-subdir強制 Atest 也包含這些測試。

atest --include-subdir

如果沒有 --include --include-subdir選項,Atest 將只運行測試 A。使用 --include --include-subdir選項,Atest 將運行兩個測試(A、B)。

支持行級註釋

您可以添加行級// - 格式註釋來充實 TEST_MAPPING 文件,其中包含對以下設置的描述。 ATest和 Trade Federation 會將 TEST_MAPPING 預處理為沒有註釋的有效 JSON 格式。為保持 JSON 文件簡潔易讀,僅支持行級//格式註釋。

例子:

{
  // For presubmit test group.
  "presubmit": [
    {
      // Run test on module A.
      "name": "A"
    }
  ]
}