Стратегии тестирования

Автоматизированное тестирование помогает улучшить качество приложений несколькими способами. Например, он помогает выполнять проверку, выявлять регрессии и проверять совместимость. Хорошая стратегия тестирования позволяет вам воспользоваться преимуществами автоматического тестирования и сосредоточиться на важном преимуществе: производительности разработчиков .

Команды достигают более высокого уровня производительности, когда используют систематический подход к тестированию в сочетании с улучшениями инфраструктуры. Это обеспечивает своевременную обратную связь о том, как ведет себя код. Хорошая стратегия тестирования делает следующее:

  • Выявляет проблемы как можно раньше.
  • Выполняется быстро.
  • Предоставляет четкие указания, когда что-то необходимо исправить.

Эта страница поможет вам решить, какие типы тестов реализовать, где их запускать и как часто.

Пирамида тестирования

Классифицировать тесты в современных приложениях можно по размеру. Небольшие тесты фокусируются только на небольшой части кода, что делает их быстрыми и надежными. Большие тесты имеют широкую область применения и требуют более сложных настроек, которые сложно поддерживать. Однако большие тесты более точны* и позволяют выявить гораздо больше проблем за один раз.

*Под верностью понимается сходство среды выполнения теста с производственной средой.

Распределение количества тестов по объему обычно визуализируется в виде пирамиды.
Рисунок 1. Распределение количества тестов по объему обычно изображается в виде пирамиды.

У большинства приложений должно быть много маленьких тестов и относительно мало больших тестов. Распределение тестов в каждой категории должно образовывать пирамиду, в которой более многочисленные мелкие тесты образуют основание, а менее многочисленные большие тесты образуют вершину.

Минимизируйте стоимость ошибки

Хорошая стратегия тестирования максимизирует производительность разработчиков и минимизирует затраты на поиск ошибок.

Рассмотрим пример возможно неэффективной стратегии. Здесь количество тестов по размеру не организовано в пирамиду. Слишком много больших сквозных тестов и слишком мало компонентных UI-тестов:

Стратегия с большим количеством пользователей, при которой многие тесты выполняются вручную, а тесты устройств выполняются только ночью.
Рис. 2. Стратегия с большим количеством пользователей, при которой многие тесты выполняются вручную, а тесты устройств выполняются только ночью.

Это означает, что перед слиянием выполняется слишком мало тестов. Если есть ошибка, тесты могут не обнаружить ее до тех пор, пока не будут запущены ночные или еженедельные сквозные тесты.

Важно учитывать, как это влияет на стоимость выявления и исправления ошибок, а также почему важно направить усилия по тестированию на более мелкие и частые тесты:

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

Тем не менее, неэффективная стратегия тестирования лучше, чем отсутствие стратегии вообще. Когда ошибка попадает в рабочую среду, исправлению требуется много времени, чтобы дойти до устройств пользователя, иногда недели, поэтому цикл обратной связи является самым длинным и самым дорогим.

Масштабируемая стратегия тестирования

Пирамида тестирования традиционно разделена на 3 категории:

  • Модульные тесты
  • Интеграционные тесты
  • Сквозные тесты.

Однако эти понятия не имеют точных определений, поэтому команды могут захотеть определить свои категории по-другому, например, используя 5 слоев:

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

Эта категоризация учитывает верность, время, объем и уровень изоляции. Вы можете проводить различные типы тестов на нескольких уровнях. Например, уровень тестирования приложения может содержать тесты поведения, скриншотов и производительности.

Объем

Доступ к сети

Исполнение

Тип сборки

Жизненный цикл

Единица

Один метод или класс с минимальными зависимостями.

Нет

Местный

Отлаживаемый

Предварительное слияние

Компонент

Уровень модуля или компонента

Несколько классов вместе

Нет

Местный
Робоэлектрик
Эмулятор

Отлаживаемый

Предварительное слияние

Особенность

Уровень функции

Интеграция с компонентами, принадлежащими другим командам.

Высмеянный

Местный
Робоэлектрик
Эмулятор
Устройства

Отлаживаемый

Предварительное слияние

Приложение

Уровень приложения

Интеграция с функциями и/или сервисами, принадлежащими другим командам.

Высмеянный
Промежуточный сервер
Прод-сервер

Эмулятор
Устройства

Отлаживаемый

Предварительное слияние
После слияния

Кандидат на выпуск

Уровень приложения

Интеграция с функциями и/или сервисами, принадлежащими другим командам.

Прод-сервер

Эмулятор
Устройства

Минимизированная сборка выпуска

После слияния
Предварительная версия

Определитесь с категорией теста

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

Например, рассмотрим, как протестировать реализацию этой функции: пользовательский интерфейс потока входа. В зависимости от того, что вам нужно протестировать, вы можете выбрать разные категории:

Объект на тесте

Описание того, что тестируется

Категория теста

Пример типа теста

Логика валидатора формы

Класс, который проверяет адрес электронной почты на соответствие регулярному выражению и проверяет, было ли введено поле пароля. У него нет зависимостей.

Модульные тесты

Локальный модульный тест JVM

Поведение пользовательского интерфейса формы входа

Форма с кнопкой, которая активируется только после проверки формы.

Тесты компонентов

Тест поведения пользовательского интерфейса, выполняемый на Robolectric

Внешний вид пользовательского интерфейса формы входа

Форма, соответствующая спецификации UX.

Тесты компонентов

Создание теста скриншота предварительного просмотра

Интеграция с менеджером авторизации

Пользовательский интерфейс, который отправляет учетные данные менеджеру аутентификации и получает ответы, которые могут содержать различные ошибки.

Функциональные тесты

Тест JVM с фейками

Диалоговое окно входа

Экран, показывающий форму входа в систему при нажатии кнопки входа.

Тесты приложений

Тест поведения пользовательского интерфейса, выполняемый на Robolectric

Критический путь пользователя: вход в систему

Полный процесс входа в систему с использованием тестовой учетной записи на промежуточном сервере.

Кандидат на выпуск

Сквозной тест поведения пользовательского интерфейса Compose, выполняемый на устройстве

В некоторых случаях принадлежность чего-либо к той или иной категории может быть субъективной. Могут быть дополнительные причины, по которым тест перемещается вверх или вниз, например, стоимость инфраструктуры, нестабильность и длительное время тестирования.

Обратите внимание, что категория теста не определяет тип теста, и не все функции должны тестироваться в каждой категории.

Ручное тестирование также может быть частью вашей стратегии тестирования. Обычно команды контроля качества проводят тесты Release Candidate, но они также могут участвовать и на других этапах. Например, исследовательское тестирование на наличие ошибок в функции без скрипта.

Тестовая инфраструктура

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

Вы можете классифицировать тесты по области действия, чтобы определить, когда и где какие тесты запускать. Например, следуя пятислойной модели:

Категория

Окружающая среда (где)

Триггер (когда)

Единица

[Местные][4]

Каждый коммит

Компонент

Местный

Каждый коммит

Особенность

Локальные и эмуляторы

Предварительное объединение, перед объединением или отправкой изменения

Приложение

Локальный, эмуляторы, 1 телефон, 1 складной

После слияния, после слияния или отправки изменения

Кандидат на выпуск

8 разных телефонов, 1 складной, 1 планшет.

Предварительная версия

  • Модульные и компонентные тесты выполняются в системе непрерывной интеграции для каждого нового коммита, но только для затронутых модулей.
  • Все тесты модулей, компонентов и функций запускаются перед объединением или отправкой изменения.
  • Тесты приложений выполняются после слияния.
  • Тесты Release Candidate проводятся каждую ночь на телефоне, складном устройстве и планшете.
  • Перед выпуском тесты Release Candidate выполняются на большом количестве устройств.

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