воскресенье, 5 февраля 2012 г.

Tips&Tricks тестировщику мобильных приложений - октябрь 2015

Cтатья представляет собой список рекомендаций и советов. Из неё вы узнаете:

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

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

Как облегчить процесс тестирования?

1. Используйте принципы эвристики и мнемоники — они помогают удержать в голове все аспекты, которые нужно учесть при тестировании фичи или приложения.

2. Скриншоты, логи и видео — лучшие аргументы тестировщика!
К сожалению, с логами «общения» с сервером зачастую не всё так гладко, как с клиентскими логами. Обычно они добавляются скорее для удобства разработчика при отладке работы с сервером, чем для работы тестировщика.

  • Попросите клиентских и серверных разработчиков выводить в удобный и понятный интерфейс для просмотра логов все запросы к серверу и ответы от него. Так будет проще анализировать запросы и ответы от сервера, выявлять дубликаты, находить более удобные способы обновления данных. Например, для обновления части профиля разработчик может перезапрашивать весь профиль вместо использования более легковесного запроса. В ситуациях, когда непонятно, где проблема, комбинация серверных и клиентских логов в большинстве случаев поможет разобраться с проблемой быстрее.
  • Научитесь добавлять клиентские логи самостоятельно (впрочем, помощь девелопера всё же может понадобиться) — избыток логов тоже вреден и загрязняет консоль.

Логи для релизной версии приложения должны быть выключены из соображений быстродействия и безопасности.

3. Используйте «обезьянок» для поиска крашей и зависаний, пока вы тестируете функционал более осмысленно. Наиболее эффективно комбинировать обезьянок и средства для снятия телеметрии для ускорения локализации проблемы, например, с TestFairy. С недавних пор TestFairy поддерживает и iOS, но пока функционал ограничен.

  • Android: Application/UI Monkey Exerciser
  • iOS: UIAutoMonkey/CrashMonkey (основывается на UIAutoMonkey). К сожалению, AntEater совсем забросили — на сайте ошибка 404. Последний раз фиксил баги и обновлял для iOS8 я сам (если вдруг кому интересно) — разработчики так и не решились передать исходный код в open source, хотя просили их неоднократно.

4. Для того чтобы чувствовать себя более комфортно перед релизами, используйте страховочную сеть в виде бета-версий. Два-три человека физически не смогут покрыть все комбинации кейсов и различных девайсов (особенно для Android), а так вы можете получить помощь от beta-пользователей по всему миру, что позволит разгрузить команду тестирования. Для удобства очень рекомендую обёртывать бета-версию в оболочку TestFairy.

  • У Android с бета-программой дела пока намного лучше, чем у iOS: можно приглашать (или ждать заявок от) пользователей через Google+. Количество бета-пользователей ограничено 10 000.
  • У iOS c TestFlight (который купила Apple) есть некоторые искусственные ограничения: максимум 2000 пользователей, серьёзное «ревью» первой бета-версии. Сервисы дистрибуции тоже можно использовать для бета-программы. Отличный обзор сервисов дистрибуции: 1234.

5. Очень удобно иметь отладочное меню с функциями, которые облегчают работу разработчикам и тестировщикам (особенно команде автоматизации). Например, с возможностью симулировать ответы от сервера, открывать определённых пользователей, выставлять определённые флаги, очищать и терять сессии, обнулять кэш. В наших мобильных приложениях создано многофункциональное отладочное меню, и я уже не представляю без него ни ручное, ни автоматизированное тестирование.

6. Девелоперское меню iOS и Android — ваш лучший друг. Включаем для iOSAndroid.
В iOS оно, например, позволяет: 
  • включить Network Link Conditioner;
  • включить логирование потребления трафика и энергии;
  • удобнее тестировать iAd рекламу.

У Android картина ещё более радужная — там есть множество настроек под любые нужды: от отображения загрузки процессора и памяти до изменения скорости анимации интерфейса.

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

8. Переходите между скринами много раз.
  • На iOS проверяется правильность работы с памятью (не обратились ли вы к неправильному участку памяти; не обновился ли экран, пока он был невидим), утечки памяти.
  • На Android могут быть утечки памяти, т.к. предыдущую активность (activity) что-то «держит».

Лучше всего переходить между скринами во время взаимодействия приложения с сетью:
  • запросы должны отменяться, если они не завершены;
  • ответ сервера на удаленный из памяти (невидимый) скрин не должен «крашить» приложение.

9. Не пренебрегайте тестированием на эмуляторах и симуляторах — очень удобная штука, которая позволяет облегчить некоторые проверки. Например, для iOS так намного проще тестировать изменения местоположения и background location updates, а также симулировать memory warning по хоткеям, включать замедленные анимации. Для Android можно конфигурировать экзотические характеристики «железа»: разрешение экрана, плотность пикселов, количество оперативной памяти, heap size, размер встроенной и внешней памяти.

10. Заполняйте оперативную память девайса перед запуском приложения. Это поможет, во-первых, провести стресс-тестирование и проверить скорость работы, а во-вторых — проверить сохранение и возобновление состояния приложения (куда мы вернемся после сворачивания приложения, запустятся ли все нужные сервисы).

11. Запускайте приложение под отладчиком. Почему?
  • Есть шанс познать дзен :)
  • Позволяет работать медленно с приложением, что иногда вскрывает баги.
  • Если в приложении случится краш или exception — оно остановится, и тогда можно будет подозвать разработчика для отладки «не отходя от кассы».

Работа с сетью

1. Приложение должно работать стабильно при:
  • нестабильном соединении;
  • отсутствующем соединении;
  • исключительно медленной скорости (1-2Kb/s);
  • отсутствии ответа от сервера;
  • неправильном ответе сервера (мусор или ошибки);
  • смене типа соединения Wi-Fi — 3G — 4G — Wi-Fi на лету.

Используйте цепочки кейсов «проблемы с сетью», по максимуму используя:
  • кастомную прошивку для роутера. В свое время меня здорово спасала прошивка Tomato для Linksys WRT54G. Роутер стоил копейки, а с помощью прошивки можно выставлять необходимую скорость Wi-Fi на лету без потери соединения с девайсами;
  • прокси;
  • WANEm;
  • Network Link Conditioner — легко ставится на Mac и встроен в iOS с версии 6.0. Им можно «зашейпить» трафик и раздать с помощью создания точки доступа как на iOS-устройстве, так и на Mac;
  • для Android можно использовать пресеты скорости соединения в эмуляторе или более гибко настроить через netspeed.

2. Если нужен прокси-сервер, то проще всего использовать CharlesProxy (есть инструкции для девайсов и эмуляторов на iOS и Android, поддерживает бинарный протокол, rewrite, throttling траффика и в целом стоит каждого вложенного цента) или Fiddler (он бесплатный). 

Работа с данными приложений, внешними и внутренними сервисами

1. Если есть сторонний сервис — он обязательно подведет. Недавняя авария у FB повлияла на работу некоторых приложений и сайтов. Например, пару версий назад приложение Habrahabr «расшаривало» статьи с блокированием UI без индикатора активности. В момент, когда «тормозил» Facebook или Интернет, «шаринг» вешал всё приложение до тех пор, пока процесс не завершался.

Лучше заранее выявить максимальное количество внештатных ситуаций и продумать шаги для их устранения: предусмотреть обработку неожиданных ответов (ошибки, мусор, отсутствие ответа, пустой ответ) от сторонних сервисов с индикацией проблемы пользователю, добавить таймауты к необходимым реквестам и т.д.

2. Если есть сторонние библиотеки — они обязательно будут вызывать проблемы. В частности Twitter, PayPal, Facebook довольно часто содержат в себе баги. Как пример, в одной из версий Twitter SDK был краш при получении 503 ошибки от собственного бэкенда — библиотека просто падала и утаскивала за собой приложение. Facebook SDK тоже нередко падает на Android (можно видеть в краш-алертах процесс под названием com.facebook.katana время от времени).

3. Парсеры URI и данных должны стараться учитывать всевозможные неожиданности — были случаи, когда автопроверка валидности файлов и (или) URI отламывалась, и приложениям приходилось вытаскивать информацию по крупицам.
Например:
  • ошибка 404 вернулась в HTML-формате;
  • в ответе 200 есть HTML или JS;
  • вернулся пустой ответ;
  • сервер на запрос к API отвечает стандартной заглушкой веб-сервера (“It works!” в случае nginx);
  • вернулась пустая структура данных (JSON, XML, PLIST);
  • вместо одной структуры данных вернулась другая (HTML вместо XML);
  • вернулся ведущий не туда или невалидный URI.

Во всех этих случаях приложение может не распарсить неожиданный ответ и упасть.

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

4. Если ваше приложение обновляет данные по статичным или легко формируемым URL-ам, то можно использовать Dropbox или Google Диск, пока логика на сервер не готова или обкатывается. Заливать или обновлять файлы напрямую на девайсе — сомнительное удовольствие.
Поэтому мы поступили так:
  • сделали все URL-ы конфигуриемыми и вынесли в отдельную сущность, чтобы команда разработки или тестирования могла легко пересобрать приложения с определёнными URL-ами для обновляемых данных;
  • далее изменили все необходимые файлы и заменили ими уже существующие (вручную или с помощью простейших скриптов). Для отката на предыдущую версию можно написать ещё один скрипт, который запишет эталонные файлы (также можно воспользоваться версионированием файлов, которую предоставляет Dropbox).

5. Не забывайте проверять миграцию данных и кэшей при обновлении приложения. Важно помнить, что пользователи могут пропускать версии, и необходимо будет проверять обновления более старых версий. В качестве примера могу привести краш на старте приложения LinkedIn в июне 2015: часть пользователей не могла запустить приложение, пока не выпустили новую версию (к счастью, она была выпущена в тот же день).

Android

1. Выставьте кастомные разрешения экрана эмулятора — это позволит выявить проблемы с layout, если у вас есть определённая нехватка девайсов или нужно проверить, правильно ли написан layout. Также разрешение экрана и плотность пикселов можно редактировать через ADB и на физическом девайсе, например, на Nexus 10.

2. Если клавиатура переопределена (используется кастомная), то уделите этому дополнительное внимание. Бывают как ошибки клавиатур, которые не удаётся обойти, так и логические или графические ошибки.

3. Staged rollout позволит легко найти проблемы, которые могли пропустить при тестировании релизной версии: можно зарелизиться на 5-10% и помониторить графики и краши, при необходимости — откатиться или перевыложить версию с фиксом.

4. Используйте do not keep activities при тестировании и убедитесь, что приложения готовы к неожиданным завершениям активностей, что может вести к крашам или потере данных.

iOS

1. Проверьте, не переопределены ли стандартные жесты. Например, при активации «Универсального Доступа» активируются дополнительные жесты, они могут конфликтовать с жестами вашего приложения (например, трёх- и четырёхпальцевый жест).

2. Также уделяйте внимание сторонним клавиатурам. Например, в iOS9 есть баг, который приведет к крашу приложения, если в модальном окне в WebView вводить текст с помощью сторонней клавиатуры.

3. Покажите разработчикам сервис rollout.io, который позволяет патчить некоторые краши на продакшене, переопределять параметры, показывать алерты с извинениями или делать некоторые кнопки неактивными. Нас он уже спасал не один раз.

4. Для интерактивного тестирования верстки или проверки того, что все скрины убрались из иерархии, можно использоватьстандартные средства Xcode или Spark InspectorRevealApp.

5. Попросите интегрировать в меню отладчика вызов Memory Warning. Его обычно вешают на определённый жест (тап несколькими пальцами, нажатие на строку состояния или навигации) или на кнопки регулирования громкости. Это нужно, чтобы проверить адекватность поведения приложения при Memory Warning, подчищает ли оно за собой ресурсы и насколько корректно это делается. Например, у нас был неприятный баг, когда после Memory Warning наш Image service выгружал картинку из памяти и на экране оставалась заглушка.

Налаживаем процессы

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

1. Введите культуру Pre-QA. Перед отправкой тикета на ревью сядьте вместе с разработчиком за его машину и потестируйте 5-10 минут фичу под отладчиком на одном-двух девайсах — большинство самых глупых ошибок найдется сразу. Это также позволяет обучить разработчиков базовым навыкам тестирования: как минимум они будут повторять за вами действия, как максимум — вникнут и будут тестировать более осмысленно. Никому не хочется допускать глупые ошибки и выставлять их на общее обозрение.

2. Хотя бы бегло просматривайте diff-ы каждой ветки (фичи) и задавайте как можно больше вопросов разработчикам. 
Таким образом вы, во-первых, поднимите свой престиж как тестировщика — вы пытаетесь разобраться в коде и областях, которые затронуты этой фичей. Даже сейчас тестировщики мобильных приложений иногда воспринимаются разработчиками как обезьянки, которые тыкают в телефон и жонглируют ими чтобы «уронить» приложение. 

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

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

3. Изучите жизненный цикл сущностей приложения и самого приложения (Activity для Android 123; ViewController для iOS 123) для понимания, из какого в какое состояние может переходить экран приложения и оно само. Чем лучше вы знаете работу приложения изнутри, тем более полно сможете его протестировать.

4. Если у вас есть приложения для iOS и Android, то важно соблюдать правильный баланс ресурсов для их тестирования.

Ошибки в приложениях грозят перевыкладкой, что влечет определённые последствия. При этом цена ошибки у платформы Android зачастую ниже.
  • У Android есть staged rollout (поэтапное внедрение). Android-приложение можно перевыложить хоть в тот же день или откатить staged rollout (до 50% раскладки можно полностью откатить на предыдущую версию). Но не стоит перевыкладываться очень часто, т.к. пользователи начнут жаловаться и ставить низкие оценки;
  • Для iOS перевыкладка производится, в лучшем случае, через expedited review (которым очень не рекомендуют злоупотреблять). Приложение будет перевыложено:
    • самое раннее — в тот же день (обычно в in review уходит в тот же день, но доступно к выкладке только на следующий);
    • в худшем случае, если не разрешили expedited review, срок увеличится до 5-10 дней.

Но, с другой стороны, iOS-приложения можно гораздо быстрее протестировать, т.к. экосистема не так сильно фрагментирована, как у Android. 

Разное

1. Что делать, если час Х подкрался в самый неподходящий момент и в продакшен попала нестабильная версия приложения? Мы используем систему экранов обновления, чтобы ускорить процесс миграции пользователей. Такая система пригодится:
  • в случае появления критичного бага, пропущенного при разработке и тестировании;
  • при быстром обновлении интересующей нас версии для:
    • запуска фичи одновременно на всех платформах (также пригодится, если изменения ломают обратную совместимость);
    • более быстрых и равномерных результатов A/B тестирования;
    • разгрузки серверной команды, которая вынуждена поддерживать устаревшие версии API из-за определённого количества пользователей, пользующихся (очень) старой версией приложения.

У нас система обновления работает в двух режимах
  • мягкий (soft-update), когда на экране есть кнопки «Обновиться» и «Пропустить» (экран можно спрятать на 24 часа; так же в этом режиме можно просить пользователей включить автообновление приложений для iOS и Android в настройках системы — некоторая часть пользователей отключает автоапдейты);
  • жесткий (hard-update) — на экране показывается только кнопка «Обновить», которая ведет сразу на страничку нашего приложения в магазине.

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

2. Необходим мониторинг самых важных метрик приложения в продакшене:
  • графики daily/monthly/… active users, чтобы быстрее реагировать на аварии;
  • системы сбора и анализа краш-логов: Crashlytics (теперь часть Twitter Fabric), HockeyAppCrittercismBugSense (теперь часть Splunk);
  • системы обратной связи от пользователей через приложение (встроенные feedback-формы или отправка письма) с возможностью отправки описания девайса и скриншотов;
  • статистики использования приложения (GoogleAnalyticsFlurrySplunkHeatmaps.ioMixPanel);
  • дайджестов скачиваний, группировки отзывов, понимания, где и когда вас зафичерили (AppAnnie — куплен Distimo).

3. Иногда проблемы возникают только у определённых пользователей с определёнными девайсами или в определённых странах. Например, у Vodafone UK были проблемы с WebP-картинками. Для проверки таких кейсов можно использовать облачные решения по аренде девайсов: DeviceAnywhere (платный сервис), PerfectoMobile (платный сервис), Samsung Device Lab (бесплатный, но есть система пойнтов, которые пополняются со временем).

4. Также не стоит забывать о временных поясах и локации пользователей. Возможно, ваше приложение не рассчитано на работу в определённых странах (хотя и выложено там по ошибке или вы, как пользователь, приехали на время в другую страну). Местоположение на iOS можно «фейкать» в настройках симулятора (Debug > Locations), а на Android есть приложения, позволяющие это делать.
Если приложение работает с данными и есть несколько дата-центров в разных временных зонах, необходимо убедиться, что все работает правильно и не возникает коллизий при переключении между дата-центрами.

5. Научитесь обновлять и «даунгрейдить» прошивки — платформы фрагментированы, особенно Android и Blackberry. Облачные сервисы хороши, но они стоят денег, поэтому не все компании имеют возможность ими пользоваться из-за недостатков финансирования или политики безопасности.

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