這類工具測試與針對常規Android應用程序的工具測試沒有什麼不同。值得注意的是,包含檢測的測試應用程序需要使用與目標應用程序相同的證書進行簽名。
請注意,本指南假定您已經對平台源代碼樹工作流程有所了解。如果沒有,請參考https://source.android.com/source/requirements。此處涵蓋的示例是編寫一個新的儀器測試,其中目標包設置在其自己的測試應用程序包中。如果您不熟悉此概念,請通讀平台測試簡介。
本指南使用以下測試作為示例:
- 框架/基礎/軟件包/外殼/測試
建議先瀏覽代碼以大致了解,然後再繼續。
確定來源位置
因為檢測測試將針對應用程序,所以約定是將測試源代碼放在平台源樹中組件源目錄的根目錄下的tests
目錄中。
在自測測試的端到端示例中查看有關源位置的更多討論。
清單文件
就像常規應用程序一樣,每個檢測測試模塊都需要一個清單文件。如果將文件命名為AndroidManifest.xml
並將其提供給測試tmodule放在Android.mk
旁邊,則BUILD_PACKAGE
核心makefile將自動包含該文件。
在繼續進行之前,強烈建議您先閱讀App Manifest概述。
概述了清單文件的基本組件及其功能。
可以在以下網址訪問用於示例gerrit更改的清單文件的最新版本:https://android.googlesource.com/platform/frameworks/base/+/master/packages/Shell/tests/AndroidManifest.xml
為了方便起見,此處包括快照:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.shell.tests">
<application>
<uses-library android:name="android.test.runner" />
<activity
android:name="com.android.shell.ActionSendMultipleConsumerActivity"
android:label="ActionSendMultipleConsumer"
android:theme="@android:style/Theme.NoDisplay"
android:noHistory="true"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.shell"
android:label="Tests for Shell" />
</manifest>
清單文件上的一些選擇說明:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.shell.tests">
package
屬性是應用程序包名稱:這是Android應用程序框架用來標識應用程序的唯一標識符(或在這種情況下:您的測試應用程序)。系統中的每個用戶只能使用該軟件包名稱安裝一個應用程序。
由於這是一個測試應用程序包,因此與被測應用程序包無關,因此必須使用不同的包名稱:一種常見的約定是添加後綴.test
。
此外,此package
屬性與ComponentName#getPackageName()
返回的屬性相同,也與通過adb shell
與各種pm
子命令進行交互所使用的屬性相同。
還請注意,儘管程序包名稱通常與Java程序包名稱具有相同的樣式,但實際上與它無關。換句話說,您的應用程序(或測試)程序包可以包含具有任何程序包名稱的類,但是,另一方面,您可以選擇簡單性,並在應用程序或測試中將頂級Java程序包名稱與應用程序程序包名稱相同。
<uses-library android:name="android.test.runner" />
這是所有Instrumentation測試所必需的,因為相關類打包在單獨的框架jar庫文件中,因此當應用程序框架調用測試包時,還需要其他類路徑條目。
android:targetPackage="com.android.shell"
這com.android.shell.tests
檢測的目標包設置為com.android.shell.tests
。通過am instrument
命令調用am instrument
,框架會重新啟動com.android.shell.tests
進程,並將檢測工具代碼注入到進程中以進行測試執行。這也意味著測試代碼將有權訪問在被測應用程序中運行的所有類實例,並且可能能夠根據暴露的測試掛鉤來操縱狀態。
簡單的配置文件
每個新的測試模塊必須具有一個配置文件,以使用模塊元數據,編譯時依賴性和打包指令來指導構建系統。在大多數情況下,基於Soong的藍圖文件選項就足夠了。有關詳細信息,請參見簡單測試配置。
複雜的配置文件
對於更複雜的測試,您還需要為Android的測試工具Trade Federation編寫一個測試配置文件。
測試配置可以指定特殊的設備設置選項和默認參數以提供測試類。
可以在以下位置訪問示例gerrit更改的配置文件的最新版本: frameworks / base / packages / Shell / tests / AndroidTest.xml
為了方便起見,此處包括快照:
<configuration description="Runs Tests for Shell.">
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="ShellTests.apk" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="ShellTests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.shell.tests" />
<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="ShellTests.apk"/>
</target_preparer>
這告訴貿易聯合會使用指定的target_preparer將ShellTests.apk安裝到目標設備上。 Trade Federation的開發人員可以使用許多目標準備器,這些目標準備器可用於確保在執行測試之前正確設置設備。
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.shell.tests"/>
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>
這指定了用於執行測試的行業聯合會測試類,並在要執行的設備上傳遞了程序包和測試運行程序框架(在本例中為JUnit)。
在此處查看有關測試模塊配置的更多信息
JUnit4功能
使用android-support-test
庫作為測試運行程序可以採用新的JUnit4風格的測試類,並且示例gerrit更改包含其功能的一些非常基本的用法。
可以在以下位置訪問示例gerrit更改的最新源代碼: frameworks / base / packages / Shell / tests / src / com / android / shell / BugreportReceiverTest.java
儘管測試模式通常特定於組件團隊,但仍有一些通常有用的使用模式。
@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {
JUnit4中的一個重要區別是不再需要從通用基礎測試類繼承測試;相反,您可以使用普通Java類編寫測試,並使用批註指示某些測試設置和約束。在此示例中,我們指示該類應作為Android JUnit4測試運行。
@SmallTest
批註為整個測試類指定了一個測試大小:添加到該測試類中的所有測試方法都繼承了該測試大小批註。測試前的類設置,測試後的拆除和測試後的拆除:類似於JUnit4中的setUp
和tearDown
方法。 Test
註釋用於註釋實際測試。
@Before
public void setup() {
...
@Test
public void testGetProvider_shouldCacheProvider() {
...
@Before
在方法上使用@Before
批註執行預測試設置。儘管在此示例中未使用,但還有@After
用於後期測試拆卸。類似地,@ @BeforeClass
和@AfterClass
批註可以由JUnit4在方法上使用,以在執行測試類中的所有測試之前執行設置,然後進行拆卸。請注意,類作用域的設置和拆卸方法必須是靜態的。
至於測試方法,與早期版本的JUnit不同,它們不再需要使用test
開頭方法名稱,而是必須使用@Test
對其進行註釋。與往常一樣,測試方法必須是公共的,不聲明任何返回值,不帶參數,並且可能引發異常。
Context context = InstrumentationRegistry.getTargetContext();
由於JUnit4測試不再需要公共基類,因此不再需要通過基類方法通過getContext()
或getTargetContext()
獲得Context
實例;相反,新的測試運行器通過InstrumentationRegistry
管理它們,在其中存儲了Instrumentation框架創建的上下文和環境設置。通過此類,您還可以調用:
-
getInstrumentation()
:Instrumentation
類的實例 getArguments()
:通過-e <key> <value>
傳遞給am instrument
的命令行參數
本地構建和測試
對於最常見的用例,請使用Atest 。
對於需要大量定制的更複雜的情況,請遵循儀器說明。