Google致力於提高黑人社區的種族平等。 怎麼看。
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

自測測試示例

啟動檢測測試時,將使用注入的檢測代碼重新啟動其目標包並啟動執行程序。一個例外是此處的目標程序包不能是Android應用程序框架本身,即程序包android ,因為這樣做會導致矛盾的情況,即需要重新啟動Android框架,這是支持系統功能(包括工具)的原因本身。

這意味著檢測測試無法將其自身注入Android框架(也稱為系統服務器)以執行。為了測試Android框架,測試代碼只能調用公共API表面,也可以調用通過平台源代碼樹中可用的Android接口定義語言AIDL公開的表面。對於此類測試,針對任何特定的程序包沒有意義。因此,習慣將此類工具聲明為針對自己的測試應用程序包,如在其自己的AndroidManifest.xml<manifest>標記中所定義。

根據要求,此類別的測試應用程序包還可能:

  • 捆綁測試所需的活動。
  • 與系統共享用戶標識。
  • 使用平台密鑰簽名。
  • 根據框架源而不是公共SDK進行編譯。

這類儀器測試有時稱為自我儀器。以下是平台源代碼中的一些自儀器測試示例:

此處涵蓋的示例是編寫一個新的儀器測試,目標包設置在其自己的測試應用程序包中。本指南以以下測試為例:

建議先瀏覽代碼以大致了解,然後再繼續。

確定源位置

通常,您的團隊將已經建立了檢入代碼的地方以及添加測試的地方。大多數團隊擁有單個git存儲庫,或與其他團隊共享一個git存儲庫,但擁有一個包含組件源代碼的專用子目錄。

假設<component source root>位於<component source root> ,大多數組件下都有srctests文件夾,以及一些其他文件,例如Android.mk (或分解為其他.mk文件),清單文件AndroidManifest.xml和測試配置文件“ AndroidTest.xml”。

由於您要添加全新的測試,因此可能需要在組件src旁邊創建tests目錄,並在其中填充內容。

在某些情況下,由於需要將不同的測試套件打包到單個apk中,因此您的團隊可能正在tests其他目錄結構。在這種情況下,您需要在tests下創建一個新的子目錄。

無論採用哪種結構,最終都將使用與示例gerrit更改的instrumentation目錄中類似的文件填充到tests目錄或新創建的子目錄中。以下各節將詳細解釋每個文件。

清單文件

就像常規應用程序一樣,每個檢測測試模塊都需要一個清單文件。如果將文件命名為AndroidManifest.xml並將其提供給測試tmodule放在Android.mk旁邊,則BUILD_PACKAGE核心makefile將自動包含該文件。

在繼續進行操作之前,強烈建議您先閱讀App Manifest概述

概述了清單文件的基本組件及其功能。請參閱platform_testing / tests / example / instrumentation / AndroidManifest.xml中的示例

為了方便起見,此處包括快照:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >

    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21" />

    <application>
        <uses-library android:name="android.test.runner" />
    </application>

    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
                     android:targetPackage="android.test.example.helloworld"
                     android:label="Hello World Test"/>

</manifest>
 

清單文件上的一些選擇說明:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >
 

package屬性是應用程序包名稱:這是Android應用程序框架用來標識應用程序的唯一標識符(或在這種情況下:您的測試應用程序)。系統中的每個用戶只能使用該軟件包名稱安裝一個應用程序。

此外,此package屬性與ComponentName#getPackageName()返回的屬性相同,也與通過adb shell與各種pm子命令進行交互所使用的屬性相同。

還請注意,儘管程序包名稱通常與Java程序包名稱具有相同的樣式,但實際上與它無關。換句話說,您的應用程序(或測試)程序包可以包含具有任何程序包名稱的類,但是,另一方面,您可以選擇簡單性,並在應用程序或測試中將頂級Java程序包名稱與應用程序程序包名稱相同。

 android:sharedUserId="android.uid.system"
 

這聲明在安裝時,應該向該apk授予與核心平台相同的用戶ID,即運行時身份。請注意,這取決於使用與核心平台相同的證書籤名的apk(請參閱上一節中的LOCAL_CERTIFICATE ),但是它們是不同的概念:

  • 一些權限或API受簽名保護,這需要相同的簽名證書
  • 某些權限或API需要調用者的system用戶身份,如果與核心平臺本身是獨立的軟件包,則要求調用程序包與system共享用戶ID。
 <uses-library android:name="android.test.runner" />
 

這是所有Instrumentation測試所必需的,因為相關類包裝在單獨的框架jar庫文件中,因此,當應用程序框架調用測試包時,還需要其他類路徑條目。

 android:targetPackage="android.test.example.helloworld"
 

您可能已經註意到,這裡的targetPackage聲明與此文件的manifest標記中聲明的package屬性相同。如測試基礎中所述 ,這種工具測試通常用於測試框架API,因此對於它們而言,擁有特定的目標應用程序包(本身除外)並不是很有意義。

簡單的配置文件

每個新的測試模塊必須具有一個配置文件,以使用模塊元數據,編譯時依賴性和打包指令來指導構建系統。在大多數情況下,基於Soong的藍圖文件選項就足夠了。有關詳細信息,請參見簡單測試配置

複雜的配置文件

對於這些更複雜的情況,您還需要為Android的測試工具Trade Federation編寫一個測試配置文件。

測試配置可以指定特殊的設備設置選項和默認參數以提供測試類。請參閱/platform_testing/tests/example/instrumentation/AndroidTest.xml中的示例。

為了方便起見,此處包括快照:

 <configuration description="Runs sample instrumentation test.">
  <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
  <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
    <option name="test-file-name" value="HelloWorldTests.apk"/>
  </target_preparer>
  <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
  <option name="test-suite-tag" value="apct"/>
  <option name="test-tag" value="SampleInstrumentationTest"/>

  <test class="com.android.tradefed.testtype.AndroidJUnitTest">
    <option name="package" value="android.test.example.helloworld"/>
    <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
  </test>
</configuration>
 

測試配置文件上的一些選擇說明:

 <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
  <option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
 

這告訴貿易聯合會使用指定的target_preparer將HelloWorldTests.apk安裝到目標設備上。 Trade Federation開發人員可以使用許多目標準備器,這些目標準備器可用於確保在執行測試之前正確設置設備。

 <test class="com.android.tradefed.testtype.AndroidJUnitTest">
  <option name="package" value="android.test.example.helloworld"/>
  <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>
 

這指定了用於執行測試的行業聯合會測試類,並在要執行的設備上傳遞了程序包和測試運行程序框架(在本例中為JUnit)。

有關更多信息,請參見測試模塊配置

JUnit4功能

使用android-support-test庫作為測試運行程序可以採用新的JUnit4樣式的測試類,並且示例gerrit更改包含其功能的一些非常基本的用法。請參閱/platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java中的示例。

儘管測試模式通常特定於組件團隊,但仍有一些通常有用的使用模式。

 @RunWith(JUnit4.class)
public class HelloWorldTest {
 

JUnit4中的一個顯著區別是不再需要從通用的基礎測試類繼承測試。相反,您可以使用普通Java類編寫測試,並使用批註指示某些測試設置和約束。在此示例中,我們指示該類應作為JUnit4測試運行。

     @BeforeClass
    public static void beforeClass() {
    ...
    @AfterClass
    public static void afterClass() {
    ...
    @Before
    public void before() {
    ...
    @After
    public void after() {
    ...
    @Test
    @SmallTest
    public void testHelloWorld() {
    ...
 

@Before在方法上使用@Before@After批註來執行測試前的設置和測試後的拆卸。同樣,JUnit4在方法上使用@BeforeClass@AfterClass批註在執行測試類中的所有測試之前執行設置,然後進行拆卸。請注意,類作用域的設置和拆卸方法必須是靜態的。至於測試方法,與早期版本的JUnit不同,它們不再需要使用test開頭方法名稱,而是必須使用@Test對其進行註釋。和往常一樣,測試方法必須是公共的,不聲明任何返回值,不帶參數,並且可能引發異常。

重要提示 :測試方法本身帶有@Test註釋;並註意,要通過APCT執行的測試,必須使用測試大小進行註釋:示例方法方法testHelloWorld@SmallTest 。註釋可以應用於方法範圍或類範圍。

訪問instrumentation

儘管基本的hello world示例中未涉及,但Android測試需要訪問Instrumentation實例是很常見的:這是核心API接口,可提供對應用程序上下文,與活動生命週期相關的測試API等的訪問。

由於JUnit4測試不再需要公共基類,因此不再需要通過InstrumentationTestCase#getInstrumentation()獲取Instrumentation實例,而是由新的測試運行器通過InstrumentationRegistry對其進行管理,該位置存儲了Instrumentation框架創建的上下文和環境設置。

要訪問Instrumentation類的實例,只需在InstrumentationRegistry類上調用靜態方法getInstrumentation()

 Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()
 

在本地構建和測試

對於最常見的用例,請使用Atest

對於需要大量定制的更複雜的情況,請遵循儀器說明