Автоматизированное тестирование помогает улучшить качество приложения несколькими способами. Например, оно помогает проводить валидацию, выявлять регрессии и проверять совместимость. Хорошая стратегия тестирования позволяет использовать преимущества автоматизированного тестирования, чтобы сосредоточиться на важном преимуществе: производительности труда разработчиков .
Команды достигают более высокой производительности, применяя системный подход к тестированию в сочетании с улучшением инфраструктуры. Это обеспечивает своевременную обратную связь о поведении кода. Хорошая стратегия тестирования обеспечивает следующее:
- Выявляет проблемы как можно раньше.
- Выполняется быстро.
- Дает четкие указания, когда что-то необходимо исправить.
Эта страница поможет вам решить, какие типы тестов следует реализовать, где их проводить и как часто.
Пирамида тестирования
Тесты в современных приложениях можно классифицировать по размеру. Небольшие тесты проверяют лишь небольшой фрагмент кода, что делает их быстрыми и надёжными. Большие тесты имеют широкую область применения и требуют более сложных настроек, которые сложно поддерживать. Однако большие тесты более точны* и могут обнаружить гораздо больше проблем за один проход.
*Под точностью понимается схожесть среды выполнения теста с производственной средой.

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

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

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