Эта категория инструментальных тестов ничем не отличается от тестов, предназначенных для обычных приложений Android. Стоит отметить, что тестовое приложение, включающее инструменты, должно быть подписано тем же сертификатом, что и целевое приложение.
Обратите внимание, что в этом руководстве предполагается, что вы уже знакомы с рабочим процессом дерева исходного кода платформы. Если нет, обратитесь к https://source.android.com/source/requirements. Описанный здесь пример — это написание нового инструментального теста с целевым пакетом, установленным в собственном пакете тестового приложения. Если вы не знакомы с этой концепцией, прочтите введение в тестирование платформы .
В этом руководстве в качестве образца используется следующий тест:
- фреймворки/база/пакеты/оболочка/тесты
Прежде чем продолжить, рекомендуется сначала просмотреть код, чтобы получить общее впечатление.
Выбор местоположения источника
Поскольку инструментальный тест будет нацелен на приложение, соглашение заключается в размещении исходного кода теста в каталоге tests
в корневом каталоге исходного кода вашего компонента в дереве исходного кода платформы.
См. дополнительные обсуждения исходного местоположения в сквозном примере для самоинструментирующих тестов .
Файл манифеста
Как и обычному приложению, каждому модулю инструментального тестирования нужен файл манифеста. Если вы назовете файл как AndroidManifest.xml
и предоставите его рядом с Android.mk
для вашего тестового tmodule, он будет автоматически включен основным make-файлом BUILD_PACKAGE
.
Прежде чем продолжить, настоятельно рекомендуется сначала просмотреть обзор манифеста приложения .
Это дает обзор основных компонентов файла манифеста и их функций.
Последняя версия файла манифеста для примера изменения 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()
, а также с тем же атрибутом, который вы могли бы использовать для взаимодействия с различными подкомандами pm
через adb shell
.
Также обратите внимание, что хотя имя пакета обычно имеет тот же стиль, что и имя пакета Java, на самом деле оно имеет очень мало общего с ним. Другими словами, пакет вашего приложения (или теста) может содержать классы с любыми именами пакетов, хотя, с другой стороны, вы можете выбрать простоту и иметь имя пакета Java верхнего уровня в вашем приложении или тесте, идентичное имени пакета приложения.
<uses-library android:name="android.test.runner" />
Это требуется для всех тестов Instrumentation, поскольку связанные классы упакованы в отдельный файл библиотеки jar фреймворка, поэтому требуются дополнительные записи пути к классам, когда тестовый пакет вызывается фреймворком приложения.
android:targetPackage="com.android.shell"
Это устанавливает целевой пакет инструментария com.android.shell
. Когда инструментирование вызывается с помощью команды am instrument
, платформа перезапускает процесс com.android.shell
и вводит код инструментирования в процесс для выполнения теста. Это также означает, что тестовый код будет иметь доступ ко всем экземплярам класса, работающим в тестируемом приложении, и может иметь возможность манипулировать состоянием в зависимости от выставленных тестовых перехватчиков.
Простой файл конфигурации
Каждый новый тестовый модуль должен иметь файл конфигурации для управления системой сборки с метаданными модуля, зависимостями времени компиляции и инструкциями по упаковке. В большинстве случаев достаточно файла Blueprint на основе 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>
Это говорит Trade Federation установить ShellTests.apk на целевое устройство, используя указанный target_preparer. Разработчикам в 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
указан размер теста для всего тестового класса: все тестовые методы, добавленные в этот тестовый класс, наследуют эту аннотацию размера теста. установка класса перед тестированием, удаление после тестирования и удаление класса после тестирования: аналогично setUp
и tearDown
в JUnit4. Аннотации к Test
используются для аннотирования фактического теста.
@Before
public void setup() {
...
@Test
public void testGetProvider_shouldCacheProvider() {
...
Аннотация @Before
используется в методах JUnit4 для выполнения предтестовой настройки. Хотя в этом примере он не используется, существует также @After
для демонтажа после тестирования. Точно так же аннотации @BeforeClass
и @AfterClass
могут использоваться в методах JUnit4 для выполнения настройки перед выполнением всех тестов в тестовом классе и последующего удаления. Обратите внимание, что методы настройки и демонтажа области класса должны быть статическими.
Что касается тестовых методов, то, в отличие от более ранней версии JUnit, им больше не нужно начинать имя метода с test
, вместо этого каждый из них должен быть аннотирован @Test
. Как обычно, методы тестирования должны быть общедоступными, не объявлять возвращаемое значение, не принимать параметров и могут генерировать исключения.
Context context = InstrumentationRegistry.getTargetContext();
Поскольку тесты JUnit4 больше не требуют общего базового класса, больше нет необходимости получать экземпляры Context
через getContext()
или getTargetContext()
через методы базового класса; вместо этого новый инструмент запуска тестов управляет ими через InstrumentationRegistry
, где хранятся настройки контекста и среды, созданные инфраструктурой инструментирования. Через этот класс вы также можете вызвать:
-
getInstrumentation()
: экземпляр классаInstrumentation
-
getArguments()
: аргументы командной строки, переданные вam instrument
через-e <key> <value>
Создавайте и тестируйте локально
Для наиболее распространенных случаев использования используйте Atest .
Для более сложных случаев, требующих более тщательной настройки, следуйте инструкциям по инструментированию .