Автоматизированное тестирование помогает улучшить качество приложения различными способами. Например, оно позволяет проводить валидацию, выявлять регрессии и проверять совместимость. Хорошая стратегия тестирования позволяет использовать преимущества автоматизированного тестирования для достижения важного результата: повышения производительности разработчиков .
Команды достигают более высокого уровня производительности, используя систематический подход к тестированию в сочетании с улучшением инфраструктуры. Это обеспечивает своевременную обратную связь о поведении кода. Хорошая стратегия тестирования делает следующее:
- Выявляет проблемы на самых ранних стадиях.
- Выполняется быстро.
- Четко указывает на необходимость ремонта.
Эта страница поможет вам решить, какие типы тестов следует внедрить, где их запускать и как часто.
навыки Android
Просмотреть на GitHub Разработайте стратегию тестирования.
android skills add --skill testing-setup
Пирамида тестирования
В современных приложениях тесты можно классифицировать по размеру. Небольшие тесты фокусируются только на небольшом участке кода, что делает их быстрыми и надежными. Большие тесты имеют широкий охват и требуют более сложных настроек, которые трудно поддерживать. Однако большие тесты обладают большей точностью* и могут выявить гораздо больше проблем за один раз.
*Под детализацией понимается сходство среды выполнения тестов с производственной средой.

Большинство приложений должны иметь множество небольших тестов и относительно небольшое количество крупных тестов. Распределение тестов в каждой категории должно образовывать пирамиду, где большее количество небольших тестов образует основание, а меньшее количество крупных тестов — вершину.
Сведите к минимуму затраты, связанные с ошибкой.
Грамотная стратегия тестирования позволяет максимально повысить производительность разработчиков, минимизируя при этом затраты на поиск ошибок.
Рассмотрим пример потенциально неэффективной стратегии. В этом случае количество тестов по размеру не выстраивается в пирамиду. Слишком много больших сквозных тестов и слишком мало компонентных тестов пользовательского интерфейса:

Это означает, что перед слиянием выполняется слишком мало тестов. Если обнаруживается ошибка, тесты могут не выявить её до тех пор, пока не будут запущены сквозные тесты, проводимые ежедневно или еженедельно.
Важно учитывать последствия этого для стоимости выявления и исправления ошибок, а также почему важно направлять усилия по тестированию на проведение более мелких и частых тестов:
- Когда ошибка обнаруживается с помощью модульного теста, её обычно исправляют за считанные минуты, поэтому затраты невелики.
- Сквозное тестирование может занять несколько дней, чтобы обнаружить одну и ту же ошибку. Это может привлечь к процессу нескольких членов команды, снизить общую производительность и потенциально задержать выпуск. Стоимость такой ошибки выше.
Тем не менее, неэффективная стратегия тестирования лучше, чем её полное отсутствие. Когда ошибка попадает в рабочую среду, исправление занимает много времени, иногда несколько недель, поэтому цикл обратной связи оказывается самым длительным и дорогостоящим.
Масштабируемая стратегия тестирования
Традиционно пирамида тестирования делится на 3 категории:
- модульные тесты
- Интеграционные тесты
- Сквозное тестирование.
Однако эти понятия не имеют точных определений, поэтому командам может потребоваться определить свои категории по-другому, например, используя 5 уровней:

- Модульный тест запускается на хост-машине и проверяет работоспособность одного функционального блока логики, не зависящего от фреймворка Android.
- Пример: проверка ошибок, связанных с отклонением на единицу, в математической функции.
- Компонентный тест проверяет функциональность или внешний вид модуля или компонента независимо от других компонентов системы. В отличие от модульных тестов, область применения компонентного теста распространяется на более высокие уровни абстракции, выходящие за рамки отдельных методов и классов.
- Пример: Тест скриншота для пользовательской кнопки
- Тестирование функций проверяет взаимодействие двух или более независимых компонентов или модулей. Тесты функций более масштабны и сложны и обычно проводятся на уровне функций.
- Пример: Тесты поведения пользовательского интерфейса , проверяющие управление состоянием на экране.
- Тест приложения проверяет функциональность всего приложения в виде развертываемого бинарного файла. Это масштабные интеграционные тесты, в которых в качестве тестируемой системы используется отлаживаемый бинарный файл, например, сборка для разработки, которая может содержать тестовые точки.
- Пример: тестирование поведения пользовательского интерфейса для проверки изменений конфигурации в складном устройстве, тестирование локализации и доступности.
- Тесты для релиз-кандидатов проверяют функциональность сборки для выпуска. Они похожи на тесты приложения, за исключением того, что исполняемый файл приложения минифицирован и оптимизирован . Это масштабные сквозные интеграционные тесты, которые выполняются в среде, максимально приближенной к производственной, без предоставления доступа к приложению публичным учетным записям пользователей или публичным бэкэндам.
- Пример: критически важные сценарии взаимодействия пользователя с системой, тестирование производительности.
Эта классификация учитывает точность, время, объем и уровень изоляции. Различные типы тестов могут проводиться на нескольких уровнях. Например, уровень тестирования приложения может включать в себя поведенческие тесты, тесты скриншотов и тесты производительности.
Объем | доступ к сети | Исполнение | Тип сборки | Жизненный цикл | |
|---|---|---|---|---|---|
Единица | Единственный метод или класс с минимальным количеством зависимостей. | Нет | Местный | Отлаживаемый | Предварительное слияние |
Компонент | На уровне модуля или компонента Несколько классов вместе | Нет | Местный | Отлаживаемый | Предварительное слияние |
Особенность | Уровень функциональности Интеграция с компонентами, принадлежащими другим командам. | Высмеяли | Местный | Отлаживаемый | Предварительное слияние |
Приложение | Уровень приложения Интеграция с функциями и/или сервисами, принадлежащими другим командам. | Высмеяли | Эмулятор | Отлаживаемый | Предварительное слияние |
Предварительная версия релиза | Уровень приложения Интеграция с функциями и/или сервисами, принадлежащими другим командам. | Производственный сервер | Эмулятор | Минимизированная сборка релиза | После слияния |
Определите категорию теста
Как правило, следует рассматривать самый нижний уровень пирамиды, который может обеспечить команде необходимый уровень обратной связи.
Например, рассмотрим, как протестировать реализацию этой функции: пользовательский интерфейс процесса авторизации. В зависимости от того, что именно нужно протестировать, вы выберете разные категории:
Предмет исследования | Описание того, что именно тестируется | Категория теста | Пример типа теста |
|---|---|---|---|
Логика валидатора формы | Класс, который проверяет адрес электронной почты по регулярному выражению и подтверждает, что пароль был введен. Он не имеет зависимостей. | модульные тесты | |
Поведение пользовательского интерфейса формы входа в систему | Форма с кнопкой, которая становится активной только после проверки формы. | Тестирование компонентов | Тестирование поведения пользовательского интерфейса запущено на Robolectric |
Внешний вид пользовательского интерфейса формы входа | Форма, соответствующая спецификации UX. | Тестирование компонентов | |
Интеграция с менеджером аутентификации. | Пользовательский интерфейс, который отправляет учетные данные менеджеру аутентификации и получает ответы, которые могут содержать различные ошибки. | Тестирование функций | |
Диалог входа в систему | Экран, отображающий форму входа в систему при нажатии кнопки авторизации. | Тестирование приложений | Тестирование поведения пользовательского интерфейса запущено на Robolectric |
Ключевой пользовательский опыт: вход в систему. | Полный процесс авторизации с использованием тестовой учетной записи на промежуточном сервере. | Предварительная версия релиза | Сквозное тестирование поведения пользовательского интерфейса Compose, запущенное на устройстве. |
В некоторых случаях принадлежность чего-либо к той или иной категории может быть субъективной. Могут быть и другие причины, по которым тестирование переносится на более ранний или более поздний срок, такие как стоимость инфраструктуры, нестабильность и длительное время тестирования.
Обратите внимание, что категория теста не определяет тип теста, и не все функции обязательно должны быть протестированы в каждой категории.
Ручное тестирование также может быть частью вашей стратегии тестирования. Как правило, команды контроля качества проводят тестирование на этапе подготовки релиза, но они также могут участвовать в других этапах. Например, в исследовательском тестировании на наличие ошибок в функционале без использования скрипта.
Тестовая инфраструктура
Стратегия тестирования должна подкрепляться инфраструктурой и инструментами, которые помогут разработчикам постоянно запускать свои тесты и обеспечивать соблюдение правил, гарантирующих прохождение всех тестов.
Вы можете классифицировать тесты по области действия, чтобы определить, когда и где запускать те или иные тесты. Например, следуя пятиуровневой модели:
Категория | Окружающая среда (где) | Триггер (когда) |
|---|---|---|
Единица | [Локальный][4] | Каждый коммит |
Компонент | Местный | Каждый коммит |
Особенность | Локальные эмуляторы | Перед слиянием или отправкой изменений выполните следующие действия: |
Приложение | Локальный, эмуляторы, 1 телефон, 1 складной | После слияния, после слияния или внесения изменений. |
Предварительная версия релиза | 8 разных телефонов, 1 складной, 1 планшет | Предварительный релиз |
- В системе непрерывной интеграции модульные и компонентные тесты запускаются при каждом новом коммите, но только для затронутых модулей.
- Все модульные, компонентные и функциональные тесты запускаются перед слиянием или отправкой изменений.
- Тестирование приложения проводится после слияния.
- Тестирование кандидатов на выпуск продукта проводится ежедневно на телефоне, складном устройстве и планшете.
- Перед выпуском продукта проводятся тесты в рамках программы Release Candidate на большом количестве устройств.
Эти правила могут меняться со временем, поскольку количество тестов влияет на производительность. Например, если вы переведете тестирование на ежедневный цикл, вы можете сократить время сборки и тестирования в рамках CI, но при этом можете увеличить продолжительность цикла обратной связи.