Основы автоматизации тестирования Android-приложений
На VK Fest 5 выступил инженер по автоматизации тестирования Алексей Тюрин. Он поделился своими знаниями об автоматизации тестирования приложений на платформе Android. Он рассказал, зачем вообще нужны автотесты, какие бывают виды, привёл примеры.
Автотесты защищают от багов
Для начала стоит понять, что автотесты — это программирование.
Автотесты нужны, чтобы защититься от багов. Для начала необходимо понять первопричину возникновения ошибок. Алексей привёл три основные причины их появления.
Почему появляются баги?
Невнимательность разработчика
Все ошибаются, и программист не исключение. Он мог не выспаться, отвлечься, или же просто отложить что-то в голове и забыть: причин много, следствие одно — баг.
Чтобы исключить подобные случаи, программист разрабатывает автотесты во время написания основного кода. Зачастую некорректное поведение выявляется в момент, когда кодер задумывается о входных/выходных условиях, крайних значениях, прочих зависимостях.
Внешние изменения в системе
Зачастую ошибка проявляется в тот момент, когда над одним проектом трудятся несколько программистов. Если по-отдельности у первого и второго программиста всё работает исправно, это может нарушиться во время «слияния».
В данной ситуации помогает автотест: ошибка просто обнаруживается и устраняется на этапе сборки приложения.
Долговременные изменения
Ошибка, возникающая зачастую при модернизации какой-либо функции. Допустим, была работоспособная фича, которую дополнили через длительное время, заменив зависимый код, вследствие чего произошел краш.
Автотесты экономят время и деньги
Естественно, ошибка обнаружится раньше при помощи автоматизации, нежели эту ошибку найдёт тестировщик. Также это облегчает задачу разработчику: автотест точно указывает на проблемный участок, и ему будет проще провести рефакторинг кода.
Чем раньше найден баг — тем меньше потери компании. В случае, если автотест не помог, настаёт час тестировщика: он заводит задачу в баг-трекере, собирает все необходимые данные, пытается воспроизвести баг и зарегистрировать его. После всего этого подключается разработчик и на основе изложенного тестировщиком пытается устранить ошибку. Иногда приходится задавать уточняющие вопросы, из-за чего время только растягивается.
Разработчик значительно экономит время, используя автотесты. Выпуская продукт быстрее, он значительно укрепляет конкурентное преимущество компании на рынке.
Автотесты избавляют от рутинной работы, развивают навыки программирования и подталкивают к более глубокому пониманию продукта и улучшению архитектуры приложения.
Виды автотестов Android
Для большего понимания Алексей рассказал о видах автоматизации при помощи пирамиды тестирования.
Unit tests — малоёмкие тесты, проверяющие самую незначительную функциональность продукта, за счёт чего довольно точно указывают местоположение ошибки.
Integration tests — тесты, проверяющие взаимодействие частей функциональности. Например, работает ли один класс вместе с другим.
UI (User interface) tests — большие тесты, занимающие длительное время тестового прогона, проверяющие взаимодействие приложения с пользователем.
Manual — отдел, занимающийся оконечным тестированием на безопасность. Эти кейсы сложно автоматизировать.
В идеале по мере усложнения автотестов их количество уменьшается, однако случается и так, что оно только возрастает.
Пирамида становится «рожком», в котором всё наоборот: на вершине огромный слой мануальных тестов, появляется необходимость автоматизировать пользовательский сценарий, от чего появляется много UI тестов, что сильно отнимает время. Кроме того, становится на порядок сложнее определить причину падения теста.
Демо-приложение. Пример
Перед началом тестирования приложения Алексей продемонстрировал, как выглядит каталог с исходным кодом.
- main — каталог, в котором хранится код проекта.
- androidTest — каталог, в котором хранятся UI и interrogation tests.
- test — каталог, в котором хранятся Unit tests.
Два последних каталога разделены неспроста: Unit-тесты выполняются на локальной Java-машине, а UI и интеграционные тесты — на девайсах или эмуляторах, где время ожидания выше.
Unit test
Разберём этот момент подробнее. Как уже упоминалось, они быстрые и могут точно локализовать проблему.
Unit tests имеют зависимости. Они нацелены на то, чтобы проверить конкретную часть кода, но это возможно не всегда: разработанный класс может зависеть от других классов, и чтобы изолировать тест от зависимостей, было придумано две библиотеки, подключающиеся к проекту: Robolectric и Mockito. Первый изолирует тест от Android-фреймворка, второй — от других классов приложения.
Тестирование
Класс хранит в себе список всех сообщений: вы можете отправить, удалить, найти нужное сообщение.
Разберём принцип работы приведённого Unit-теста. Вначале необходимо подготовить тестовые данные.
Затем получаем исходное число сообщений в репозитории.
Добавляем новое сообщение в репозиторий.
Получаем новое число сообщений.
Число сообщений увеличивается на единицу.
Однако одного теста недостаточно для проверки метода AddNewMessage: для проверки одного метода нужно писать больше Unit-тестов.
Алексей написал пять Unit-тестов и провёл небольшую демонстрацию тестирования.
В отчёте указывается, какой был ожидаемый и фактический результат. Это был Unit-тест на получение добавленного сообщения, который выдал ожидаемый неблагоприятный результат.
Время выполнения очень быстрое: 15 ms.
Integration tests
Выглядит этот тест практически как и Unit test, с той лишь разницей, что здесь подключаются зависимости операционной системы и других классов приложения.
Такие тесты выполняются на устройстве или эмуляторе, причём единожды на разных версиях Android, что позволяет проверить работу приложения в разном окружении, в отличие от Unit-тестов, выполняющихся на Java-машине.
Интеграционные тесты лучше писать там, где нужно проверить работу вашего приложения на Android.
UI tests
Тесты пользовательского интерфейса — самые интересные, но самые продолжительные и нестабильные.
Пример UI-теста: откроем чат, очистим историю сообщений, напишем новое, отправим и проверим корректность отображения.
Так выглядит самый простой тест на Espresso-фреймворке.
Вначале создаём текст сообщения и сохраняем его в объект.
Затем при помощи onView кликаем по конкретному диалогу.
Открываем меню внутри диалога на три точки.
Заполняем поле ввода и отправляем сообщение.
Выполняем проверку того, отображается ли ожидаемый текст на экране.
Готово.
А вот так выглядит более стабильный тест. К слову, здесь есть специально сделанная ошибка. На VK Fest 5 Алексей предложил зрителям найти баг и написать ему.
Раньше в случае, если функциональность нужно было модифицировать, приходилось править участок кода каждого теста, которых мог быть не один десяток, на что уходило много времени.
Путём долгих эволюций тесты стали выглядеть подобным образом, в которых замена проходит за пару минут.
UI test. Демонстрация
На небольшом видеофрагменте продемонстрирована работа нескольких UI-тестов.
Пять UI-тестов выполнились за 16 секунд, в то время как пять Unit-тестов выполнились за 15 миллисекунд, что на порядок дольше.
Запись выступления можно посмотреть ниже. (30:20 — 1:01:30)
The Brown Room — независимое интернет-издание про социальные сети и современные технологии
Автор: Илья Филиппов
Корректор: Арсений Метелев
Слайды и данные: Алексей Тюрин / VK Testers
Фото на превью: VK Testers
