Эта категория тестирования инструментария не сильно отличается от тех, которые нацелены на обычные приложения Android. Стоит отметить, что тестовое приложение, включающее инструментарий, должно быть подписано тем же сертификатом, что и приложение, на которое оно нацелено.
Обратите внимание, что это руководство предполагает, что у вас уже есть некоторые знания о рабочем процессе дерева исходного кода платформы. Если нет, обратитесь к разделу Требования . В данном примере рассматривается написание нового теста инструментирования с целевым пакетом, установленным в его собственном пакете тестового приложения. Если вы не знакомы с этой концепцией, прочитайте раздел Введение в тестирование платформы .
В этом руководстве в качестве примера используется следующий тест:
- фреймворки/база/пакеты/оболочка/тесты
Рекомендуется сначала просмотреть код, чтобы получить общее представление, прежде чем продолжить.
Определите местоположение источника
Поскольку инструментальный тест будет нацелен на приложение, принято размещать исходный код теста в каталоге tests
в корневом каталоге исходного кода компонента в дереве исходного кода платформы.
Дополнительные обсуждения о местоположении источника см. в примере сквозного тестирования для самоинструментирования .
Файл манифеста
Как и обычное приложение, каждый тестовый модуль инструментирования нуждается в файле манифеста. Если вы назовете файл AndroidManifest.xml
и предоставите его рядом с Android.mk
для вашего тестового tmodule, он будет автоматически включен основным makefile BUILD_PACKAGE
.
Прежде чем продолжить, настоятельно рекомендуется сначала ознакомиться с обзором манифеста приложения .
Здесь дается обзор основных компонентов файла манифеста и их функций.
Последнюю версию файла манифеста для примера изменения gerrit можно получить по адресу: https://android.googlesource.com/platform/frameworks/base/+/main/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" />
Это необходимо для всех тестов инструментирования, поскольку соответствующие классы упакованы в отдельный файл библиотеки jar фреймворка, поэтому требуются дополнительные записи classpath, когда тестовый пакет вызывается фреймворком приложения.
android:targetPackage="com.android.shell"
Это устанавливает целевой пакет инструментария на com.android.shell
. Когда инструментарий вызывается через команду am instrument
, фреймворк перезапускает процесс com.android.shell
и внедряет код инструментария в процесс для выполнения теста. Это также означает, что тестовый код будет иметь доступ ко всем экземплярам классов, запущенным в тестируемом приложении, и может иметь возможность манипулировать состоянием в зависимости от выставленных тестовых хуков.
Простой файл конфигурации
Каждый новый тестовый модуль должен иметь файл конфигурации для управления системой сборки с метаданными модуля, зависимостями времени компиляции и инструкциями по упаковке. В большинстве случаев достаточно опции файла Blueprint на основе Soong. Подробнее см. в разделе Simple Test Configuration .
Сложный файл конфигурации
Для более сложных тестов вам также необходимо написать файл конфигурации теста для тестового инструментария 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>
Он указывает тестовый класс Trade Federation, который будет использоваться для выполнения теста, и передает пакет на устройство, которое будет выполняться, а также фреймворк запуска тестов, которым в данном случае является 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
, где хранятся контекстные и средовые настройки, созданные фреймворком instrumentation. Через этот класс вы также можете вызывать:
-
getInstrumentation()
: экземпляр классаInstrumentation
-
getArguments()
: аргументы командной строки, переданныеam instrument
через-e <key> <value>
Сборка и тестирование локально
Для наиболее распространенных случаев использования используйте Atest .
В более сложных случаях, требующих более серьезной настройки, следуйте инструкциям по использованию приборов .