自 2025 年 3 月 27 日起,我們建議您使用 android-latest-release
而非 aosp-main
建構及貢獻 AOSP。詳情請參閱「Android 開放原始碼計畫變更」。
在 Trade Federation 中編寫主機驅動測試
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
本頁面說明如何編寫由主機驅動的 JUnit4 風格裝置測試。也就是說,套件的主機端會觸發針對裝置的動作。
請注意,我們認為「主機端」測試和「主機驅動」測試略有不同:
- 主機導向測試:在主機上執行的測試,可與一或多部裝置互動。測試系統 (SUT) 並非位於主機上,而是由主機進行測試。
- 主機端測試:純粹在主機上執行的測試,且只在主機上測試某些項目,例如單元測試。
為何要建立主機導向測試,而不是檢測設備測試?
有些測試可能會影響裝置的整體狀態,例如發出重新啟動指令。在檢測設備測試案例中,重新啟動會終止檢測作業,導致測試無法繼續進行,且無法取得任何結果。
主機導向測試也可以引導其他設定步驟,這些步驟需要與測試依賴的外部裝置互動。
主機導向測試可處理這些用途,並允許針對裝置進行進階測試,以涵蓋更多情境。如果您遇到這種情況,編寫主機導向測試是最合適的做法。
如何使用 TF 編寫主機導向測試?
以下是範例:
@RunWith(DeviceJUnit4ClassRunner.class)
public class SampleHostJUnit4DeviceTest extends BaseHostJUnit4Test {
@Before
public void setUp() throws Exception {
// Some setup
}
@Test
public void testCheckWeHaveDevice() throws Exception {
Assert.assertNotNull(getDevice());
}
}
Trade Federation 中的主機導向測試是由 DeviceJUnit4ClassRunner JUnit4 測試執行器驅動。測試類別的整體結構與一般 JUnit4 測試相同:
@BeforeClass
@Before
@Test
@After
@AfterClass
Assume
、Assert
擴充 BaseHostJunit4Test 是繼承實用測試公用程式 API 的方法,例如:
installPackage
:允許在目標裝置上安裝 APK。
installPackageAsUser
:允許以使用者身分在目標裝置上安裝 APK。
uninstallPackage
:允許解除安裝 APK。
isPackageInstalled
:檢查套件是否已安裝。
hasDeviceFeature
:檢查裝置是否支援某項功能。(pm list features
)
runDeviceTests(DeviceTestRunOptions options)
:使用 DeviceTestRunOptions 針對目標裝置執行檢測設備測試,以便處理所有可能的選項。
並提供 Tradefed 裝置物件的存取權:
getDevice()
:傳回 TF 裝置物件,用於操控裝置。
getBuild()
:傳回 BuildInfo TF 物件,以便取得建構相關資訊。
getAbi()
:傳回測試執行的 ABI。
Tradefed 支援:依類別準備及清理裝置
JUnit4 @BeforeClass
和 @AfterClass
僅適用於靜態方法,因此無法使用 #getDevice()
處理常式,針對每個類別執行某些裝置專屬的一次性設定或清理作業。如要解決這個問題,請使用 Tradefed 註解。
- @BeforeClassWithInfo:在 @BeforeClass 註解之前執行
- @AfterClassWithInfo:在 @AfterClass 註解之後執行
@BeforeClassWithInfo
public static void beforeClassWithDevice(TestInformation testInfo) {
assertNotNull(testInfo.getDevice());
testInfo.properties().put("mytest:test-prop", "test");
}
@AfterClassWithInfo
public static void afterClassWithDevice(TestInformation testInfo) {
assertNotNull(testInfo.getDevice());
testInfo.properties().put("mytest:test-prop", "test");
}
TestInformation
可讓您使用裝置和商店屬性,這些屬性可在靜態或非靜態範圍中使用。BaseHostJUnit4Test
支援透過 #getTestInformation()
在非靜態範圍中取得 TestInformation
。
如果您未擴充 BaseHostJUnit4Test
,可以實作 ITestInformationReceiver
來接收 TestInformation
物件。
在 Tradefed XML 設定檔中,主機導向測試會透過 HostTest 執行器執行。
<test class="com.android.tradefed.testtype.HostTest" >
<option name="class" value="android.sample.cts.SampleHostJUnit4DeviceTest" />
</test>
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-27 (世界標準時間)。"],[],[],null,["# Write a host-driven test in Trade Federation\n\nThis page describes how to write a JUnit4-style device test driven by the host.\nThis means that the host side of the harness is going to trigger actions against\nthe device.\n\nNote that we consider \"host-side\" tests and \"host-driven\" tests to be slightly\ndifferent:\n\n- host-driven test: Is a test running on the host that interacts with one or more devices. The system under test (SUT) is not on the host itself but is being tested from the host.\n- host-side test: Is a test purely running on the host and testing something only on the host, for example unit tests.\n\nWhy create a host-driven test rather than an instrumentation test?\n------------------------------------------------------------------\n\nSome tests might require you to affect the device overall state, like issuing a\nreboot command. In the instrumentation test case, a reboot would kill the\ninstrumentation, the test could not continue, and no results would be available.\n\nHost-driven tests can also drive additional setup steps that require interaction\nwith external devices on which the test depends on.\n\nA host-driven test can handle these use cases and allow for advanced testing of\nthe device with more scenarios. If you are in that situation, writing a\nhost-driven test makes the most sense.\n\nHow are host-driven tests written in TF?\n----------------------------------------\n\nHere is a sample: \n\n @RunWith(DeviceJUnit4ClassRunner.class)\n public class SampleHostJUnit4DeviceTest extends BaseHostJUnit4Test {\n @Before\n public void setUp() throws Exception {\n // Some setup\n }\n\n @Test\n public void testCheckWeHaveDevice() throws Exception {\n Assert.assertNotNull(getDevice());\n }\n }\n\nHost-driven tests in Trade Federation are driven by the [DeviceJUnit4ClassRunner](https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/android16-release/test_framework/com/android/tradefed/testtype/DeviceJUnit4ClassRunner.java)\nJUnit4 test runner. The overall structure of the test class is the same as a\nregular JUnit4 test:\n\n- `@BeforeClass`\n- `@Before`\n- `@Test`\n- `@After`\n- `@AfterClass`\n- `Assume`, `Assert`\n\nExtending [BaseHostJunit4Test](https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/android16-release/test_framework/com/android/tradefed/testtype/junit4/BaseHostJUnit4Test.java)\nis a way to inherit useful testing utilities API such as:\n\n- `installPackage`: Allows to install an APK on the target device.\n- `installPackageAsUser`: Allows to install an APK as a user on the target device.\n- `uninstallPackage`: Allows to uninstall an APK.\n- `isPackageInstalled`: Check whether a package is installed or not.\n- `hasDeviceFeature`: Check whether device supports a feature or not. (`pm list features`)\n- `runDeviceTests(DeviceTestRunOptions options)`: Run an instrumentation test against a target device using [DeviceTestRunOptions](https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/android16-release/test_framework/com/android/tradefed/testtype/junit4/DeviceTestRunOptions.java) to handle all the possible options.\n\nAlso provide access to the Tradefed device object:\n\n- `getDevice()`: Returns a TF device object for manipulating the device.\n- `getBuild()`: Returns a build info TF object to get information about the build.\n- `getAbi()`: Returns the ABI the test is running against.\n\nTradefed support: Per-class device preparation and clean up\n-----------------------------------------------------------\n\nJUnit4 `@BeforeClass` and `@AfterClass` are only applicable to static methods,\nwhich makes it impossible to use the `#getDevice()` handler to do some\ndevice-specific, one-time, per-class setup or clean up. To solve this issue, use\nthe Tradefed annotation.\n\n- @BeforeClassWithInfo: Runs before @BeforeClass annotations\n- @AfterClassWithInfo: Runs after @AfterClass annotations\n\n @BeforeClassWithInfo\n public static void beforeClassWithDevice(TestInformation testInfo) {\n assertNotNull(testInfo.getDevice());\n testInfo.properties().put(\"mytest:test-prop\", \"test\");\n }\n\n @AfterClassWithInfo\n public static void afterClassWithDevice(TestInformation testInfo) {\n assertNotNull(testInfo.getDevice());\n testInfo.properties().put(\"mytest:test-prop\", \"test\");\n }\n\n`TestInformation` allows you to use the device and store properties that can be\nused either in the static or non-static scope. `BaseHostJUnit4Test` supports\ngetting the `TestInformation` in a non-static scope via `#getTestInformation()`.\n\nIf you are not extending `BaseHostJUnit4Test`, you can implement\n`ITestInformationReceiver` in order to receive the `TestInformation` object.\n\nHow to configure a host-driven test in Tradefed?\n------------------------------------------------\n\nIn Tradefed XML configuration file, host-driven tests are run through the\n[HostTest](https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/android16-release/test_framework/com/android/tradefed/testtype/HostTest.java)\nrunner. \n\n \u003ctest class=\"com.android.tradefed.testtype.HostTest\" \u003e\n \u003coption name=\"class\" value=\"android.sample.cts.SampleHostJUnit4DeviceTest\" /\u003e\n \u003c/test\u003e"]]