Google is committed to advancing racial equity for Black communities. See how.
Эта страница была переведа с помощью Cloud Translation API.
Switch to English

Ориентация на пример приложения

Эта категория инструментальных тестов не сильно отличается от тех, которые предназначены для обычных приложений Android. Стоит отметить, что тестовое приложение, включающее инструментарий, должно быть подписано тем же сертификатом, что и приложение, на которое оно нацелено.

Обратите внимание, что в этом руководстве предполагается, что у вас уже есть некоторые знания о рабочем процессе дерева исходного кода платформы. Если нет, обратитесь к https://source.android.com/source/requirements. Рассмотренный здесь пример - написание нового инструментального теста с целевым пакетом, установленным в собственном пакете тестового приложения. Если вы не знакомы с этой концепцией, прочитайте введение в тестирование платформы .

В этом руководстве в качестве образца используется следующий тест:

  • рамки / база / пакеты / оболочка / тесты

Прежде чем продолжить, рекомендуется сначала просмотреть код, чтобы получить общее представление.

Выбор местоположения источника

Поскольку инструментальный тест нацелен на приложение, соглашение заключается в размещении исходного кода tests каталоге 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() , а также тот же атрибут, который вы использовали бы для взаимодействия с различными ComponentName#getPackageName() pm через adb shell .

Также обратите внимание, что, хотя имя пакета обычно имеет тот же стиль, что и имя пакета Java, на самом деле оно имеет очень мало общего. Другими словами, ваш пакет приложения (или теста) может содержать классы с любыми именами пакетов, хотя, с другой стороны, вы можете выбрать простоту и иметь имя пакета Java верхнего уровня в вашем приложении или тесте, идентичном имени пакета приложения.

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

Это требуется для всех тестов Instrumentation, поскольку связанные классы упакованы в отдельный файл библиотеки jar фреймворка, поэтому требуются дополнительные записи пути к классам, когда тестовый пакет вызывается фреймворком приложения.

android:targetPackage="com.android.shell"

Это устанавливает целевой пакет инструментария на com.android.shell.tests . Когда инструментарий вызывается с помощью команды am instrument , фреймворк перезапускает процесс com.android.shell.tests и внедряет код инструментария в процесс для выполнения теста. Это также означает, что тестовый код будет иметь доступ ко всем экземплярам класса, запущенным в тестируемом приложении, и сможет управлять состоянием в зависимости от выставленных тестовых хуков.

Простой файл конфигурации

Каждый новый тестовый модуль должен иметь файл конфигурации, чтобы управлять системой сборки с помощью метаданных модуля, зависимостей времени компиляции и инструкций по упаковке. В большинстве случаев достаточно использовать файл 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. Разработчикам в Торговой федерации доступно множество целевых подготовителей, которые можно использовать для обеспечения правильной настройки устройства перед выполнением теста.

<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 указан размер теста для всего тестового класса: все тестовые методы, добавленные в этот тестовый класс, наследуют эту аннотацию размера теста. предварительная настройка класса тестирования, завершение тестирования после тестирования и tearDown класса после тестирования: аналогично setUp и tearDown в JUnit4. Аннотации Test используются для аннотации фактического теста.

    @Before
    public void setup() {
    ...
    @Test
    public void testGetProvider_shouldCacheProvider() {
    ...

Аннотация @Before используется в методах JUnit4 для выполнения предварительной настройки теста. Хотя это не используется в этом примере, есть также @After для @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 .

Для более сложных случаев, требующих более тяжелой настройки, следуйте инструкциям по приборам .