Привет, Хабр!
Для начала представлюсь: я тестировщик мобильных приложений в компании ATI.SU. Чаще тестирую приложения под Android, но в этом году моя команда ступила на кроссплатформенный путь, используя технологию Flutter. В этой статье расскажу, в чём особенности тестирования приложения на Flutter под iOS и Android и чем оно отличается от тестирования нативного приложения.
![](https://habrastorage.org/getpro/habr/upload_files/b03/7f7/525/b037f7525aac835736a5f922d259da6d.png)
Как сэкономить время и на что потом его потратить
Мы выбрали Flutter, так как нам было нужно приложение сразу на две платформы. Оказалось, что можно сэкономить время не только в процессе разработки, но и при тестировании.
Для ускорения тестирования мы придумали стратегию: на каждой из платформ (iOS и Android) тестируем только платформ-специфическую функциональность, а всё остальное тестируем на одной платформе.
Что является платформ-специфическими функциональностями:
разрешения приложения (permissions): доступ к файловой системе, камере, гео- разрешения и т.д;
сервисы приложения;
взаимодействие с web view;
пуш-уведомления.
А также стоит учитывать особенности разных версий одной платформы, как и при нативном тестировании.
Что не является платформ-специфическими функциональностями:
UI и вёрстка: цвета, шрифты, расположение элементов;
работа кнопок;
выполнение сетевых запросов и обработка ответов;
реакция на сетевые ошибки, таймаут и отсутствие сети;
работа с БД, миграции БД;
тосты;
перевороты экрана;
смена часового пояса и даты;
функциональные части приложения (или бизнес-логика).
Про последний пункт добавлю, что может быть функциональность, которая по ТЗ должна отличаться на разных платформах, например:
дополнительные элементы интерфейса, только на iOS/Android;
особенности анимаций;
особенности в цветовой схеме.
Также в ближайшее время мы приступим к покрытию приложения автотестами, которые достаточно будет написать один раз вместо двух по сравнению с тестами для нативных приложений.
Таким образом, кроссплатформенность приложения и подход к его тестированию могут сэкономить немало времени. Но сначала стоит разобраться в технических деталях.
Особенности релизной и дебажной сборки
Для тестирования мы используем и дебажную, и релизную версии. Дебаг-версия в первую очередь нужна нам для проксирования, сбора логов в случае ошибок, проверки основной бизнес-логики. На релизной версии мы проверяем анимации, переходы между экранами, скорость отрисовки элементов, производительность и запуск, если в дебажной версии заметили баги. Непосредственно перед релизом проводим тестирование на релизной сборке.
В отличие от нативных приложений, у Flutter-приложения производительность дебажной сборки существенно ниже, чем у релизной. Это может приводить к более медленному отклику и «подвисаниям». Причина такой разницы кроется в виртуальной машине (Dart VM) и JIT (just in time) компиляторе, которые используются для дебаг-версий. (Dart — это язык, который используют для написания Flutter приложений).
Проксирование
Обычно при тестировании нативного приложения для проксирования нужно:
открыть сниффер на компьютере (опустим подробности его настройки);
в настройках девайса задать прокси-сервер для wifi-сети, указав ip-адрес и порт компьютера с включенным сниффером;
скачать и установить на девайсе сертификат сниффера.
В Flutter-приложении такой способ не сработает, потому что http client, встроенный в dart, и популярный клиент dio не используют настройки proxy-сервера, установленные на девайсе. У этих клиентов настройки изолированы от платформ, поэтому настройки проксирования можно реализовать только внутри приложения. Для удобства тестирования разработчики сделали QA-экран, на котором можно прописать адрес и порт.
![QA-экран: настройки Proxy QA-экран: настройки Proxy](https://habrastorage.org/getpro/habr/upload_files/896/2bb/329/8962bb3299fe5064a61cf522962eff83.png)
QA-экран
QA-экран — это внутренняя функциональность, доступная только в дебаг-версии приложения. Она используется для технических настроек приложения, полезных для тестирования: прокси, включение-отключение фичей и дебаг опций, настройка фичей, а также сбор логов для дальнейшего прикрепления их к задаче или баг-репорту.
Приведу несколько примеров использования QA-экрана для тестирования бизнес-логики.
1. У вас есть экран с пагинацией данных. Чтобы протестировать все кейсы пагинации быстрее, очень удобно конфигурировать limit-offset свойства на этом экране. То есть, на экране существует настройка, ограничивающая количество элементов в пачке пагинации.
2. У вас есть скрытые фичи, открываемые при конфигурации фича-флагов. Обычно такие флаги лежат в Firebase или другом ремоут-конфиге. Чтобы не зависеть от настроек ремоут-конфига, удобнее изменять эти опции внутри приложения.
3.В вашем приложении есть какой-то бэкграунд сервис. Можно управлять жизненным циклом сервиса через QA-экран для эмулирования его поведения.
Из-за кроссплатформенности Flutter не поддерживает некоторые привычные Android-тестировщикам опции. Например, UI-опции в настройках разработчика. Давайте посмотрим на эту проблему подробнее.
Тестирование UI-элементов
Как известно, на платформе Android в настройках разработчика есть опции, важные для тестирования UI. Обнаружилось, что некоторые опции для тестирования UI не работают в Flutter-приложении. Например, «показывать границы объектов».
Такое поведение вызвано тем, что Flutter использует собственную систему рендеринга, основанную на графической библиотеке skia. Для операционной системы (как IOS, так и Android) экран Flutter-приложения — это просто окно рендер-системы, в котором происходит прорисовка элементов, поэтому она не может выделить границы.
Чтобы тестировать UI, разработчики добавили на QA-экран дебаг-опции.
![QA-экран: дебаг-опции QA-экран: дебаг-опции](https://habrastorage.org/getpro/habr/upload_files/af5/577/af5/af5577af58d06b005672bb3d2ba354d2.png)
Опишу некоторые дебаг-опции, которыми мы пользовались:
checkerboardRasterCacheImages — проверить, какие картинки кешируются;
debugShowMaterialGrid — нарисовать сетку;
debugPaintPointersEnabled — кнопки мигают во время нажатия;
debugPaintSizeEnabled — для каждого объекта отрисовки добавить видимые границы, отобразить отступы и направление выравнивания, а также направления скролла для элементов, поддерживающих скролл;
debugPaintLayerBordersEnabled — отобразить границы каждого слоя отрисовки;
debugRepaintRainbowEnabled — отобразить границы каждого слоя отрисовки, при повышении частоты отрисовок границы элементов окрашиваются в разные цвета;
debugRepaintTextRainbowEnabled — аналогично debugRepaintRainbowEnabled пометить цветовым индикатором элементы, которые регулярно переписываются, но относятся к текстовым элементам;
showPerformanceOverlay — отобразить график времени построения и отображения кадра.
Более подробно о различных дебаг-опциях для UI написано в этой статье.
Тестирование стилей
В разработке приложения отдельной болью является перенос дизайна с макетов. Для решения этой проблемы мы использовали популярное решение: токенизацию системы стилей в приложении. Мы сформулировали отдельные токен-системы для текстов и для цветов.
Для упрощения тестирования токенов мы сделали два отдельных экрана, на которых можно визуально сравнить запланированные дизайнерами токены в Figma и их реализацию в приложении.
![Экраны для тестирования стилей Экраны для тестирования стилей](https://habrastorage.org/getpro/habr/upload_files/1ef/9f3/91d/1ef9f391d118b6b74f6987476b4daf6d.png)
Как известно, в iOS есть два варианта стилей для текста: text и display. Для стиля text расстояние между символами больше, чем для display. При автоматическом переносе стилей, весь текст в iOS был в стиле text. Однако не везде в приложении нам это подходило, поэтому для тестирования стилей разработчики добавили таблицу стилей в дебаг-версию приложения. С помощью этой таблицы мы провели дизайн-ревью и решили изменить стили текста некоторых элементов для iOS-версии. Также в дебаг-сборку приложения мы добавили таблицу цветовых токенов, чтобы быть уверенными, что цвета в приложении соответствуют цветам на макетах.
Про стили поговорили, теперь давайте рассмотрим инструменты разработчика, которые есть во Flutter-приложении — Flutter Dev Tools.
Flutter Dev Tools
Flutter Dev Tools — это мощный инструмент для отладки и тестирования Flutter-приложения. В нём есть множество полезных опций как для тестировщика, так и для разработчика: монитор производительности, использование памяти, сниффер, логи.
Чтобы попасть в инструмент, необходимо:
установить плагин Flutter в Android Studio;
запустить Flutter приложение из Android Studio;
открыть Flutter Dev Tools.
![Открыть Flutter Dev Tools из Android Studio Открыть Flutter Dev Tools из Android Studio](https://habrastorage.org/getpro/habr/upload_files/aac/0b1/ac1/aac0b1ac1ee0fe1643ac1e9f4ca5cf04.png)
В браузере откроется страница Flutter Dev Tools.
![Flutter Dev Tools Flutter Dev Tools](https://habrastorage.org/getpro/habr/upload_files/cb4/845/c5f/cb4845c5f2389b41ac2e921999537b47.png)
А теперь немного подробнее расскажу про функции Dev Tools, полезные тестировщику.
Perfomance. Здесь можно отслеживать производительность приложения в FPS (frames per second). По вертикальной шкале указано время отрисовки кадра в миллисекундах. Если пиковые значения превышают 16 ms, стоит задуматься о том, чтобы пофиксить такое поведение. За производительностью имеет смысл наблюдать только на релизной сборке.
![Flutter Dev Tools: Perfomance Flutter Dev Tools: Perfomance](https://habrastorage.org/getpro/habr/upload_files/d7e/b28/51f/d7eb2851fb6709e11a2e7d11b39a6f9f.png)
Memory. Показывает использование памяти приложением. При появлении пиковых значений может потребоваться фикс от разработчиков, так как у пользователей бывают слабые устройства с небольшим количеством памяти.
![Flutter Dev Tools: Memory Flutter Dev Tools: Memory](https://habrastorage.org/getpro/habr/upload_files/4d8/760/c66/4d8760c663ab91d48fb2a40b1cb712b7.png)
Network. Это простой сниффер, но без возможности подмены трафика. Он не требует дополнительных настроек на девайсе или установки сертификатов, а также отлавливает не только http, но и web-socket.
![Flutter Dev Tools: Network, HTTP Flutter Dev Tools: Network, HTTP](https://habrastorage.org/getpro/habr/upload_files/09f/3c4/35d/09f3c435db657a78b8b334a71b692640.png)
![Flutter Dev Tools: Network, WebSocket Flutter Dev Tools: Network, WebSocket](https://habrastorage.org/getpro/habr/upload_files/6b8/084/641/6b8084641dc1c06110db73ec1339c375.png)
Logging.Тут все просто — это логи. Их можно сортировать по времени, сообщению и типу. Также есть строка поиска.
И напоследок — впечатления
Приложение, написанное на Flutter, сложно отличить от нативного — с точки зрения и пользователя, и ручного тестировщика. Приложение выглядит идентично на iOS и Android, поэтому пользователю не приходится привыкать к особенностям реализации при переезде на другую платформу.
Наше приложение разработано для бизнеса и внутреннего использования, поэтому там нет большого количества анимаций и сложной графики. Оно не проседает в скорости запуска и производительности на релизных сборках. UI отзывчивый, и его также сложно отличить от нативного.
Кроме этого, для тестировщика есть очевидные плюсы: сокращение времени тестирования и знакомство с новой технологией, поэтому общее впечатление от тестирования Flutter-приложения складывается очень позитивное.
P.S. Посмотрите, как переводится слово “flutter”. Возможно, вы удивитесь и тоже упорхнёте в кроссплатформу!