На этой странице изложены основные принципы тестирования приложений для Android, включая ключевые рекомендации и их преимущества.
Преимущества тестирования
Тестирование является неотъемлемой частью процесса разработки приложений. Регулярно запуская тесты для своего приложения, вы можете проверить его корректность, функциональность и удобство использования до публичного выпуска.
Вы можете протестировать свое приложение вручную , пройдясь по нему. Можно использовать разные устройства и эмуляторы, изменить язык системы и попытаться сгенерировать все ошибки пользователя или пройти все сценарии взаимодействия с пользователем.
Однако ручное тестирование плохо масштабируется, и легко упустить из виду регрессии в поведении вашего приложения. Автоматизированное тестирование предполагает использование инструментов, которые выполняют тесты за вас, что быстрее, обеспечивает большую воспроизводимость и, как правило, позволяет получить более полезную обратную связь о вашем приложении на ранних этапах разработки.
Типы тестов в Android
Мобильные приложения — сложные разработки, требующие хорошей работы в самых разных средах. Поэтому существует множество типов тестирования.
Предмет
Например, существуют разные типы тестов в зависимости от предмета :
- Функциональное тестирование : делает ли мое приложение то, что от него ожидается?
- Тестирование производительности : выполняется ли оно быстро и эффективно?
- Тестирование доступности : насколько хорошо оно работает с сервисами обеспечения доступности?
- Тестирование на совместимость : хорошо ли оно работает на всех устройствах и на всех уровнях API?
Объем
Тесты также различаются в зависимости от размера или степени изоляции :
- Модульные или небольшие тесты проверяют лишь очень малую часть приложения, например, метод или класс.
- Сквозные тесты или масштабные тесты проверяют одновременно большие части приложения, например, весь экран или пользовательский сценарий.
- Промежуточные тесты проверяют интеграцию между двумя или более модулями.

Существует множество способов классификации тестов. Однако для разработчиков приложений наиболее важным является то, где выполняются тесты.
Инструментальные и локальные тесты
Вы можете запускать тесты на устройстве Android или на другом компьютере:
- Инструментальные тесты запускаются на устройстве Android, как физическом, так и эмулированном. Приложение собирается и устанавливается вместе с тестовым приложением , которое внедряет команды и считывает состояние. Инструментальные тесты обычно представляют собой тесты пользовательского интерфейса, запускающие приложение и последующее взаимодействие с ним.
- Локальные тесты выполняются на вашей машине разработчика или сервере, поэтому их также называют тестами на стороне хоста . Обычно они небольшие и быстрые, изолируя тестируемый объект от остальной части приложения.

Не все модульные тесты выполняются локально, и не все сквозные тесты запускаются на устройстве. Например:
- Для масштабного локального тестирования можно использовать Android-симулятор, работающий локально, например, Robolectric .
- Небольшой инструментальный тест : Вы можете проверить, хорошо ли ваш код работает с той или иной функцией фреймворка, например, с базой данных SQLite. Вы можете запустить этот тест на нескольких устройствах, чтобы проверить интеграцию с различными версиями SQLite.
Примеры
Следующие фрагменты кода демонстрируют, как взаимодействовать с пользовательским интерфейсом в инструментальном тесте пользовательского интерфейса , который при щелчке по элементу проверяет отображение другого элемента.
Эспрессо
// When the Continue button is clicked
onView(withText("Continue"))
.perform(click())
// Then the Welcome screen is displayed
onView(withText("Welcome"))
.check(matches(isDisplayed()))
Compose UI
// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()
// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()
Этот фрагмент кода демонстрирует часть модульного теста для ViewModel (локальный тест на стороне хоста):
// Given an instance of MyViewModel
val viewModel = MyViewModel(myFakeDataRepository)
// When data is loaded
viewModel.loadData()
// Then it should be exposing data
assertTrue(viewModel.data != null)
Тестируемая архитектура
При тестируемой архитектуре приложения код следует структуре, которая позволяет легко тестировать различные его части изолированно. Тестируемые архитектуры имеют и другие преимущества, такие как лучшая читаемость, удобство сопровождения, масштабируемость и повторное использование.
Архитектура, которую невозможно протестировать, приводит к следующему результату:
- Более масштабные, медленные и нестабильные тесты. Классы, которые невозможно протестировать с помощью модульных тестов, возможно, придётся покрывать более масштабными интеграционными тестами или тестами пользовательского интерфейса.
- Меньше возможностей для тестирования различных сценариев. Более масштабные тесты выполняются медленнее, поэтому тестирование всех возможных состояний приложения может оказаться нереалистичным.
Чтобы узнать больше о рекомендациях по архитектуре, ознакомьтесь с руководством по архитектуре приложений .
Подходы к разделению
Если вы можете выделить часть функции, класса или модуля из остальной части кода, тестирование становится проще и эффективнее. Эта практика известна как декомпозиция, и это концепция, наиболее важная для тестируемой архитектуры.
К распространенным методам разделения относятся следующие:
- Разделите приложение на слои , такие как «Презентация», «Домен» и «Данные». Вы также можете разделить приложение на модули , по одному на каждую функцию.
- Избегайте добавления логики к сущностям с большими зависимостями, таким как активности и фрагменты. Используйте эти классы в качестве точек входа во фреймворк, а логику пользовательского интерфейса и бизнес-логику перенесите в другое место, например, в Composable, ViewModel или слой предметной области.
- Избегайте прямых зависимостей от фреймворков в классах, содержащих бизнес-логику. Например, не используйте Android Contexts в ViewModels .
- Сделайте зависимости легко заменяемыми . Например, используйте интерфейсы вместо конкретных реализаций. Используйте внедрение зависимостей , даже если вы не используете фреймворк для внедрения зависимостей.
Следующие шаги
Теперь, когда вы знаете, почему нужно тестировать, и два основных типа тестов, вы можете прочитать статью «Что тестировать» или узнать о стратегиях тестирования.
В качестве альтернативы, если вы хотите создать свой первый тест и учиться на практике, ознакомьтесь с учебными материалами по тестированию .